Stripes: I can pre-populate a form, but after submit the formBean is null - stripes

I can pre-populate my Stripes JSP form with an object, client in my case, but when I submit this form, my object is returning as null.
I have created a second "temp" object that is a parallel duplicate of client and this retains its values, so I can't see an issue passing an object in the request
My form is as follows :
<s:form beanclass="com.jameselsey.salestracker.action.ViewClientAction">
<s:hidden name="clientA" value="${actionBean.clientA}"/>
<s:hidden name="clientId" value="${actionBean.clientId}"/>
<table>
<tr>
<td>Name : </td>
<td><s:text name="client.name"/></td>
</tr>
<tr>
<td>Sector : </td>
<td><s:text name="client.sector"/></td>
</tr>
<!-- omitted some attirbutes, not needed here -->
</table>
</s:form>
My action looks like
public class ViewClientAction extends BaseAction
{
#SpringBean
ClientService clientService;// = new ClientService();
private Integer clientId;
private Client client;
private Client clientA;
public void setClient(Client client)
{
this.client = client;
}
public Integer getClientId()
{
return clientId;
}
public void setClientId(Integer clientId)
{
this.clientId = clientId;
}
public Client getClientA()
{
return clientA;
}
public void setClientA(Client clientA)
{
this.clientA = clientA;
}
public Client getClient()
{
return client;
}
#DefaultHandler
public Resolution quickView()
{
clientA = clientService.getClientById(clientId);
client = clientService.getClientById(clientId);
return new ForwardResolution("/jsp/viewClientQuickView.jsp");
}
public Resolution save()
{
clientService.persistClient(client);
return new ForwardResolution("/jsp/reports.jsp");
}
public Resolution viewClientInfo()
{
client = clientService.getClientById(clientId);
return new ForwardResolution("/jsp/viewClientClientInfo.jsp");
}
...
If I set a breakpoint at clientService.persistClient(client); I can see that ClientA has all of the original values of the object, yet client is nulled.
Have I missed something that binds the form bean to the client object in my action?
Thanks

Add this line in your JSP:
<s:hidden name="client" value="${actionBean.client}"/>

I got this scenario working by adding a #Before method to re-hydrate the nested object. After this, save works properly
#Before(stages = LifecycleStage.BindingAndValidation)
public void rehydrate() {
if (context.getRequest().getParameter("save")!=null){
this.domainObject = getHibernateSession().load(DomainObject.class, context.getRequest().getParameter("id"));
}
}
public void save(){
Session session=getHibernateSession();
session.update(domainObject);
session.commit();
//...
}

Related

Cannot convert MultipartFile into Blob in Spring

I am trying to save an uploaded file as Blob in a MySql record. I am new to Spring. When I am about to save the record after uploading a file, then when my POST method updateCandidate() executes, I get this exception:
Field error in object 'candidateForm' on field 'cv': rejected value [org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile#59c09df6]; codes [typeMismatch.candidateForm.cv,typeMismatch.cv,typeMismatch.java.sql.Blob,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [candidateForm.cv,cv]; arguments []; default message [cv]]; default message [Failed to convert property value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'java.sql.Blob' for property 'cv'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'java.sql.Blob' for property 'cv': no matching editors or conversion strategy found]
What is going wrong? How to fix?
My entity:
import java.sql.Blob;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
#Entity
public class Candidate {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(unique = true)
private String ssn;
private String name;
private String surname;
private String technology;
private String media;
#Lob
private Blob cv;
private boolean activeCV;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getSsn() {
return ssn;
}
public void setSsn(String ssn) {
this.ssn = ssn;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getTechnology() {
return technology;
}
public void setTechnology(String technology) {
this.technology = technology;
}
public String getMedia() {
return media;
}
public void setMedia(String media) {
this.media = media;
}
public Blob getCv() {
return cv;
}
public void setCv(Blob cv) {
this.cv = cv;
}
public boolean isActiveCV() {
return activeCV;
}
public void setActiveCV(boolean activeCV) {
this.activeCV = activeCV;
}
}
In my service:
#Autowired
private CandidateRepository repository;
...
public Optional<Candidate> getCandidate(Long id){
return repository.findById(id);
}
public void addOrUpdateCandidate(Candidate candidate) {
repository.save(candidate);
}
In my controller:
#Controller
#RequestMapping("/candidates")
public class CandidateController {
#Autowired
private EntityManagerFactory emf;
#Autowired
private CandidateService service;
...
#GetMapping("/updateCandidate/{id}")
public String showUpdateUserForm(#PathVariable("id") Long id, Model model) {
Candidate candidate = service.getCandidate(id).get();
model.addAttribute("candidateForm", candidate);
return "updateCandidateForm";
}
#PostMapping("/updateCandidate/updateCandidateResult")
public String updateCandidate(#ModelAttribute("candidateForm") Candidate candidate, #RequestParam("cv") MultipartFile file) throws IOException {
InputStream iStream = file.getInputStream();
long size = file.getSize();
Session session = emf.unwrap(Session.class);
Blob cv = Hibernate.getLobCreator(session).createBlob(iStream, size);
candidate.setCv(cv);
service.addOrUpdateCandidate(candidate);
return "updateCandidateResult";
}
}
My updateCandidateForm.jsp:
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<body>
<form:form method="POST" action="updateCandidateResult" modelAttribute="candidateForm" enctype="multipart/form-data">
<form:hidden path="id"/>
<table>
<tr>
<td><form:label path="name">Name</form:label></td>
<td><form:input path="name"/></td>
</tr>
<tr>
<td><form:label path="surname">Surname</form:label></td>
<td><form:input path="surname"/></td>
</tr>
<tr>
<td><form:label path="ssn">SSN</form:label></td>
<td><form:input path="ssn"/></td>
</tr>
<tr>
<td><form:label path="technology">Known Technology</form:label></td>
<td><form:input path="technology"/></td>
</tr>
<tr>
<td><form:label path="media">Found us on</form:label></td>
<td><form:input path="media"/></td>
</tr>
<tr>
<td><form:label path="cv">Select a cv</form:label></td>
<td><input type="file" name="cv" /></td>
</tr>
<tr>
<td><form:label path="activeCV">Active CV</form:label></td>
<td><form:checkbox path="activeCV" /></td>
</tr>
<tr>
<td><input type="submit" value="Submit"/></td>
</tr>
</table>
</form:form>
</body>
In my POM:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
EDIT 1 (question):
Would there be even a way of preventing Spring from trying to convert MultipartFile to Blob at "Submit-time", triggering this operation sooner, having the POST method already manage the Candidate (with Blob field already set) object?
EDIT 2:
as suggested by JB Nizet, I tried to use a support POJO, which has the field CV of the type MultipartFile, to store temporarily what I post via form (text fields + file field), and I don't get that exception anymore, because at "Submit-time" the populated object has the cv field of the type of the uploaded file:
import org.springframework.web.multipart.MultipartFile;
public class CandidatePOJO {
private Long id;
private String ssn;
private String name;
private String surname;
private String technology;
private String media;
private MultipartFile cv;
private boolean activeCV;
#Override
public String toString() {
return "CandidatePOJO [id=" + id + ", ssn=" + ssn + ", name=" + name + ", surname=" + surname + ", technology="
+ technology + ", media=" + media + ", cv=" + cv + ", activeCV=" + activeCV + "]";
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getSsn() {
return ssn;
}
public void setSsn(String ssn) {
this.ssn = ssn;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getTechnology() {
return technology;
}
public void setTechnology(String technology) {
this.technology = technology;
}
public String getMedia() {
return media;
}
public void setMedia(String media) {
this.media = media;
}
public MultipartFile getCv() {
return cv;
}
public void setCv(MultipartFile cv) {
this.cv = cv;
}
public boolean isActiveCV() {
return activeCV;
}
public void setActiveCV(boolean activeCV) {
this.activeCV = activeCV;
}
}
in controller, now my first concern is to see whether the pojo can be correctly instantiated, so my GET-POST pair is:
#GetMapping("/updateCandidate/{id}")
public String showUpdateUserForm(#PathVariable("id") Long id, Model model) {
CandidatePOJO candidatePOJO = new CandidatePOJO();
candidatePOJO.setId(id);
model.addAttribute("candidateForm", candidatePOJO);
return "updateCandidateForm";
}
#PostMapping("/updateCandidate/updateCandidateResult")
public String updateCandidate(#ModelAttribute("candidateForm") CandidatePOJO candidatePOJO) {
System.out.println("CANDIDATE POJO");
System.out.println(candidatePOJO.toString()); // here I notice id = null
/* MultipartFile to Blob conversion */
// MultipartFile file = candidatePOJO.getCv();
// InputStream iStream = file.getInputStream();
// long size = file.getSize();
// Session session = emf.unwrap(Session.class);
// Blob cv = Hibernate.getLobCreator(session).createBlob(iStream, size);
/* instantiating the entity object to be freezed in db */
// Candidate candidate = new Candidate();
// set all data from candidatePOJO..
// candidate.setCv(cv);
// service.addOrUpdateCandidate(candidate);
return "updateCandidateResult";
}
and I get a CandidatePOJO object with no id set. I don't manage to have the id pass from GET to POST. Does anyone know what is gong wrong?
EDIT 3:
after many days I opted for the solution with a support POJO, unbelievably I am noticing that the ID is passed from the GET method to the POST one (I haven't changed anything, I have just performed the classical Maven project cleaning as I did when I posted my issue). Unluckily I am facing now another exception (after restoring the code previously commented in the POST method, of course):
javax.persistence.PersistenceException: Hibernate cannot unwrap EntityManagerFactory as 'org.hibernate.Session'
How to fix that?
EDIT 4:
Exception just above solved replacing:
Session session = emf.unwrap(Session.class);
with:
EntityManager em = emf.createEntityManager();
Session session = (Session) em.getDelegate();
BY USING SUPPORT POJO, I finally solved. Indeed I had already solved earlier, by code. The code in the post is right (EDIT 2). When I often performed Maven project cleaning, this didn't discover the errors. I performed it in the last hours and unbelievably my code worked. I can't guess the magic :D I don't know what really happened. By code, I solved in two different ways. First:
#Autowired
private EntityManagerFactory emf;
// ........
#GetMapping("/updateCandidate/{id}")
public String showUpdateUserForm(#PathVariable("id") Long id, Model model) {
Candidate candidate = service.getCandidate(id).get();
CandidatePOJO candidatePOJO = new CandidatePOJO();
candidatePOJO.setId(id);
candidatePOJO.setName(candidate.getName());
candidatePOJO.setSurname(candidate.getSurname());
candidatePOJO.setSsn(candidate.getSsn());
candidatePOJO.setMedia(candidate.getMedia());
candidatePOJO.setTechnology(candidate.getTechnology());
candidatePOJO.setActiveCV(candidate.isActiveCV());
model.addAttribute("candidateForm", candidatePOJO);
return "updateCandidateForm";
}
#PostMapping("/updateCandidate/updateCandidateResult")
public String updateCandidate(#ModelAttribute("candidateForm") CandidatePOJO candidatePOJO) throws IOException {
MultipartFile file = candidatePOJO.getCv();
InputStream iStream = file.getInputStream();
long size = file.getSize();
EntityManager em = emf.createEntityManager();
Session session = (Session) em.getDelegate();
Blob cv = Hibernate.getLobCreator(session).createBlob(iStream, size);
Candidate candidate = new Candidate();
candidate.setId(candidatePOJO.getId());
candidate.setName(candidatePOJO.getName());
candidate.setSurname(candidatePOJO.getSurname());
candidate.setSsn(candidatePOJO.getSsn());
candidate.setMedia(candidatePOJO.getMedia());
candidate.setTechnology(candidatePOJO.getTechnology());
candidate.setActiveCV(candidatePOJO.isActiveCV());
candidate.setCv(cv);
service.addOrUpdateCandidate(candidate);
return "updateCandidateResult";
}
Second (with the same GET):
#PostMapping("/updateCandidate/updateCandidateResult")
public String updateCandidate(#ModelAttribute("candidateForm") CandidatePOJO candidatePOJO) throws IOException, SerialException, SQLException {
MultipartFile file = candidatePOJO.getCv();
Blob cv = new SerialBlob(file.getBytes());
Candidate candidate = new Candidate();
candidate.setId(candidatePOJO.getId());
candidate.setName(candidatePOJO.getName());
candidate.setSurname(candidatePOJO.getSurname());
candidate.setSsn(candidatePOJO.getSsn());
candidate.setMedia(candidatePOJO.getMedia());
candidate.setTechnology(candidatePOJO.getTechnology());
candidate.setActiveCV(candidatePOJO.isActiveCV());
candidate.setCv(cv);
service.addOrUpdateCandidate(candidate);
return "updateCandidateResult";
}
Being new to Spring, I don't know the differences yet. I would appreciate a lot an explanation. Moreover, I want to modify, sooner or later, this code, in order to get rid of the support POJO and to work with just the entity objects: if anyone can solve my initial issue, I would be forever grateful!

An error happened during template parsing

Code
Order
public class Order {
private String id;
private BigDecimal amount;
//get set constructor constructors
}
IndexController
#Controller
public class IndexController {
#GetMapping
public String index() {
return "index";
}
}
OrderController
#Controller
#RequestMapping("/orders")
public class OrderController {
private final OrderService orderService;
public OrderController(OrderService orderService) {
this.orderService = orderService;
}
#GetMapping
public Mono<String> list(Model model) {
var orders = orderService.orders();
model.addAttribute("orders", orders);
return Mono.just("orders/list");
}
}
OrderGenerator
public class OrderGenerator {
public Order generate() {
var amount = ThreadLocalRandom.current().nextDouble(1000.00);
return new Order(UUID.randomUUID().toString(), BigDecimal.valueOf(amount));
}
}
OrderService
#Service
public class OrderService {
private final Map<String, Order> orders = new ConcurrentHashMap<>(10);
#PostConstruct
public void init() {
var generator = new OrderGenerator();
for (int i = 0; i < 25; i++) {
var order = generator.generate();
orders.put(order.getId(), order);
}
}
public Mono<Order> findById(String id) {
return Mono.justOrEmpty(orders.get(id));
}
public Mono<Order> save(Mono<Order> order) {
return order.map(this::save);
}
private Order save(Order order) {
orders.put(order.getId(), order);
return order;
}
public Flux<Order> orders() {
return Flux.fromIterable(orders.values()).delayElements(Duration.ofMillis(128));
}
}
html
<body>
<h1>Orders</h1>
<table>
<thead>
<tr>
<th></th>
<th>Id</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr th:each="order : ${orders}">
<td th:text="${order.id}"></td>
<td th:text="${#numbers.formatCurrency(order.amount)}"
style="text-align: right"></td>
</tr>
</tbody>
</table>
</body>
error
An error happened during template parsing (template: "class path resource [templates/orders/list.html]")
Exception evaluating SpringEL expression: "order.id" (template: "orders/list" - line 19, col 9)
EL1008E: Property or field 'id' cannot be found on object of type 'reactor.core.publisher.FluxOnAssembly' - maybe not public or not valid?
I do not how to solve the problem, i hope you can help me.thanks for you reply.
You need to add reactive primitives like Flux and Mono as IReactiveDataDriverContextVariable.
IReactiveDataDriverContextVariable reactiveDataDrivenMode =
new ReactiveDataDriverContextVariable(orders);
model.addAttribute("orders", reactiveDataDrivenMode);
check that you are using spring-boot-starter-webflux instead of spring-boot-starter-web

Sping MVC and hibernate: undeclared variable in jsp become null when saved

I just created my simple web application using Spring frameworks and hibernate. But I face the crucial problem when there is a transaction with my database.
When I tried to update my object, undeclared variables become null when saved to the database.
I will explain it with an example.
Model.java:
public class Model implements Serializable {
private int id;
private String firstName;
private String lastName;
private String description;
//setter getter
}
ModelDaoImpl.java:
#Repository("modelDao")
public class ModelDaoImpl implements ModelDao {
#Autowired
SessionFactory sessionFactory;
public Model create (Model model) throws Exception {
this.sessionFactory.getCurrentSession().save(model);
return model;
}
public Model update (Model model) throws Exception {
this.sessionFactory.getCurrentSession().update(model);
return model;
}
public Model get (Serializable id) throws Exception {
return (Model) this.sessionFactory.getCurrentSession().get(Model.class, id);
}
}
ModelServiceImpl.java:
#Service("modelService")
public class ModelServiceImpl implements ModelService {
#Autowired
modelDao modelDao;
#Transactional
public Model create (Model model) throws Exception {
return modelDao.create(model);
}
#Transactional
public Model update (Model model) throws Exception {
return modelDao.udpdate(model);
}
#Transactional
public Model get (Serializable id) throws Exception {
return modelDao.get(id);
}
}
ModelController.java:
#Controller
public class ModelController {
#Autowired
ModelService modelService
#RequestMapping(value="/editModel", method.RequestMethod.GET)
public String formCreator(ModelMap model, HttpServletRequest request) {
Integer id = new Integer(request.getParameter("id"));
Model modelData = new Model();
if (id != null) {
modelData = modelService.get(id);
}
model.addAttribute("modelData", modelData);
return "editModel"
}
#RequestMapping(value="/saveModel", method.RequestMethod.POST)
public String saveData(#ModelAttribute("modelData") Model modelData) {
if (modelData.getId() == null) {
modelService.create(modelData);
} else {
modelService.update(modelData);
}
return "redirect:/modelList";
}
//SKIP FOR GET MODEL LIST AND GET MODEL DETAIL
}
editModel.jsp:
<form:form action="${pageContext.request.contextPath}/saveModel" method="POST" modelAttribute="modelData">
<table>
<form:hidden path="id"/>
<tr>
<td>First Name:</td>
<td><form:input path="firstName"/></td>
</tr>
<tr>
<td>Last Name:</td>
<td><form:input path="lastName"/></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="Save"></td>
</tr>
</table>
</form:form>
From jsp page we see that I didn't declare variable 'description', but when update my existing data the variable 'description' become null. I have tried using #DynamicUpdate or related to dynamic update process, but the result was still the same, the variable 'description' still become null.
Any suggestion?
The problem is that the way your controller is written: a new Model instance is created
and populated on execution of saveData.
You can update your code to be like the below. Now on POST the Model instance
will be that returned from getModel() rather than a new instance and only the
values specified in the incoming request wil be updated. We can also update the GET to use the same code to populate the model.
Essentially then:
on GET - the model will be populated for the UI by a call to #ModelAttribute
on POST - the model will be populated and the Model instance returned will be passed to saveData();
See:
https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-modelattrib-method-args
#Controller
public class ModelController {
#Autowired
ModelService modelService
#RequestMapping(value="/editModel", method.RequestMethod.GET)
public String formCreator(HttpServletRequest request) {
return "editModel"
}
#RequestMapping(value="/saveModel", method.RequestMethod.POST)
public String saveData(#ModelAttribute("modelData") Model model) {
//you can have 1 method in your service and DAO
//DAO can use saveOrUpdate() method of session;
modelService.persist(model);
return "redirect:/modelList";
}
#ModelAttribute("modelData")
public Model getModel(#RequestParam(name = "id", required = false)Integer id){
return id != null ? modelService.get(id) : new Model();
}
}

Model Attributes null with Thymeleaf-spring boot

I have a weird error that is driving me crazy.
I have a Controller with two different Get Methods - for two different url mappings.
URL1 works perfectly fine, with URL2, I get
[THYMELEAF][http-nio-8080-exec-3] Exception processing template
"questionnaireForm": Error during execution of processor
'org.thymeleaf.standard.processor.attr.StandardEachAttrProcessor'
(questionnaireForm:10)
caused by
java.lang.NullPointerException: null at org.thymeleaf.context.WebSessionVariablesMap.hashCode(WebSessionVariablesMap.java:276) ~[thymeleaf-2.1.4.RELEASE.jar:2.1.4.RELEASE]
After hours of checking each line, it's clear that my Controller Get Method is adding a non-null object to the Model.addAttribute before calling the view.
I've also removed all of my code from the template and just added the following to troubleshoot:
<tr th:each="var : ${#vars}">
<td th:text="${var.key}"></td>
<td th:text="${var.value}"></td>
This is returning the same null error as well!
The only thing i could find on the web was a bug with Thymeleaf 2.1.4 that was caused by not having a HttpSession Object
https://github.com/thymeleaf/thymeleaf/issues/349
but then again, my URL1 works fine!
I haven't posted any code here because I'm not sure what else to post, please ask!
EDIT: Added Controller Code. /admin/questions is URL1 that works fine, '/admin/questionnaires' is URL2 that doesn't work.
#Controller
public class AdminController {
private QuestionRepository questionRepository;
private EQuestionnaireRepository eQuestionnaireRepository;
private EQuestionnaire eQuestionnaire;
#Autowired
public AdminController(QuestionRepository questionRepository,
EQuestionnaireRepository
eQuestionnaireRepository){
this.questionRepository = questionRepository;
this.eQuestionnaireRepository = eQuestionnaireRepository;
eQuestionnaire = eQuestionnaireRepository.findAll().get(0);
}
#RequestMapping(value = "/admin/questions", method=RequestMethod.GET)
public String questionForm(Model model) {
model.addAttribute("question", new Question());
return "questionForm";
}//-->This Works fine
#RequestMapping(value = "/admin/questions", method=RequestMethod.POST)
public String saveQuestion(#ModelAttribute Question newQuestion, BindingResult bindingResult, Model model) {
if( bindingResult.hasErrors())
{
System.out.println(bindingResult);
System.out.println("BINDING RESULTS ERROR");
return "questionForm";
}
questionRepository.save(newQuestion);
return "questionForm";
}
#RequestMapping(value = "/admin/Questionnaires", method=RequestMethod.GET)
public String QuestionnaireForm(Model model){
model.addAttribute("ListofQ",eQuestionnaire.getQuestionList());
return "questionnaireForm";
UPDATE: I changed over to thymeleaf 2.1.5-SNAPSHOT, and now I'm not getting the previously mentioned error - but a different error:
There was an unexpected error (type=Internal Server Error, status=500).
Exception evaluating SpringEL expression: "ask.questionText"
(questionnaireForm:13)
So now, the object reference is null in the template. It's not null when i put it into the Model (i've got System.out of the getQuestionText method inside the GET method, so thats confirmed)
This is the simple code I'm trying in the template:
<table>
<tr th:each= "ask : ${ListofQ}"></tr>
<tr th:text= "${ask.questionText}"></tr>
</table>
Here is the Question Object:
#Entity
#Table(name = "Questions")
public class Question {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long ID;
private int sequence;
private String questionText;
private int weightage;
private String option1 = "option1";
private String option2 = "option2";
private String option3 = "option3";
public Question() {
}
public Long getID() {
return ID;
}
public void setID(Long iD) {
ID = iD;
}
public int getSequence() {
return sequence;
}
public void setSequence(int sequence) {
if (sequence > 0) this.sequence = sequence;
}
public String getQuestionText() {
return questionText;
}
public void setQuestionText(String questionText) {
this.questionText = questionText;
}
public int getWeightage() {
return weightage;
}
public void setWeightage(int weightage) {
this.weightage = weightage;
}
public void setOption1(String option1) {
this.option1 = option1;
}
public void setOption2(String option2) {
this.option2 = option2;
}
public void setOption3(String option3) {
this.option3 = option3;
}
public String getOption1() {
return option1;
}
public String getOption2() {
return option2;
}
public String getOption3() {
return option3;
}
output in "each" need to be in the same statement , i think this will work for you
<table>
<tr th:each= "ask : ${ListofQ}" th:text= "${ask.questionText}"></tr>
</table>
You are not returning the model object to the Thymeleaf.
Try something like this:
#RequestMapping(value = "/admin/Questionnaires", method=RequestMethod.GET)
public ModelAndView QuestionnaireForm(Model model){
return return new ModelAndView("questionnaireForm", "ListofQ",eQuestionnaire.getQuestionList());
}

Spring receive data from the client

Good evening!
public class Order {
private int idOrder;
private Basket basket;
// getter and setter
}
public class AnonymousOrder {
private String name;
private String telephone;
// getter and setter
}
public class UserOrder {
private User user;
// getter and setter
}
public class OrdersForm {
private List< ? extends Order> orders;
// getter and setter
}
#RequestMapping(value="/showOrders")
public String showOrders(Model model){
List<? extends Order> orders= adminManager.searchAllOrders();
OrdersShowForm ordersForm = new OrdersShowForm();
ordersForm.setOrders(orders);
model.addAttribute("ordersForm", ordersForm);
return "showOrders";
}
#RequestMapping(value="/showOrders", method = RequestMethod.POST)
public String showOrdersPOST(#ModelAttribute("ordersForm") OrdersShowForm ordersForm){
System.out.print(ordersForm);
return "showOrders";
}
<form:form modelAttribute="ordersForm">
<table class="features-table" border="1">
<c:forEach items="${ordersForm.orders}" var="order" varStatus="status">
<tr>
<c:if test="${order['class'].simpleName != 'UserOrder'}">
<td>
<input name="orders[${status.index}].name" value="${order.name}"/>
</td>
</c:if>
</c:forEach>
</table>
Problem: I am passing on page two types of data: UserOrder and AnonymousOrder, but when I try to get them on the server then come data type Order.
Question: How to transfer data to the server without changing their actual type?
P.S. sorry for my English)

Resources