Setting property of POJO from List in JSP - java

I have a form to set values for bean. This form has a List, every address consist of street, city, zip. How to set value of street for example to street ?
Piece of code
//List
List<Address> addressList ; //with getter and setter
//Address POJO with getters and setters
private String city;
private String zipCode;
private String street;
//JSP
<form:form id="form" commandName="form" acceptCharset="UTF-8">
<c:forEach items="${form.addressList}" var="ad">
<input value="${ad.street}" id="addressList"name="addressList.street" type="text" />
</c:forEach>
</form:form>
$.ajax({
type : "POST",
url : url,
data : $('#form').serialize(),
contentType : "application/x-www-form-urlencoded;charset=UTF-8",
I'm sending form by ajax to controller.
With List of Strings I'm getting in controller expected results, but with this POJO I'm getting null value.
How to solve this problem ?

You addressList is not a part of Form and you are reading it from form object.
<c:forEach items="${form.addressList}" var="ad">
It should be
<c:forEach items="${addressList}" var="ad">

Related

Thymeleaf Option Without Selection

From the controller, I have returned an object containing a list of objects. I want to display these list of objects in the dropdown with no pre-selection(or default value i.e. "Select Dish"), but dropdown is shown with pre-selected last value in the list.
Controller:
#GetMapping(path = "/createOrder")
public ModelAndView displayOrder(OrderFormDetails order) {
ModelAndView mav = new ModelAndView();
mav.addObject("order", orderService.displayOrder());
mav.setViewName("createOrder");
return mav;
}
Model:
public class OrderFormDetails {
#NotEmpty(message = "*Please provide your name")
private String name;
#NotEmpty(message = "*Please provide your address")
private String address;
private List < Dish > dishes;
View:
<select class="form-control" th:field="*{dishes}" id="dropOperator">
<option value="" selected="selected">Sélect dish</option>
<option th:each="dish, itemStat : *{dishes}" th:value="*{dishes[__${itemStat.index}__].id}" th:text="*{dishes[__${itemStat.index}__].title}">
</option>
</select>
I have tried multiple tricks, but none of them worked. Thanks...
Usually you don't want to mix possible options and selected option together within one field (as you apparently did). All you need to do is to decouple those things. Possible steps may be helpful:
Since OrderFormDetails acts like your form backing bean, it should contain a placeholder for selected value (Dish.id) instead of List with possible dishes. Change your OrderFormDetails to the following:
public class OrderFormDetails {
#NotEmpty(message = "*Please provide your name")
private String name;
#NotEmpty(message = "*Please provide your address")
private String address;
private T selectedDish;
// getters, setters, rest of the class omitted
...where T is the type assigned to Dish.id field.
Possible (selectable) dishes should be provided separately as a model attribute. Add following line to your displayOrder method:
mav.addObject("dishes", getDishes());
...where getDishes() returns List<Dish> containing all dishes being an option for an user.
Adjust your view to work with updated approach:
<select class="form-control" th:field="*{selectedDish}" id="dropOperator">
<option value="" selected="selected">Sélect dish</option>
<option th:each="dish : ${dishes}" th:value="${dish.id}" th:text="${dish.title}">
</option>
</select>
That's all. Such an approach is also shown in documentation - th:field on <select> level refers to form backing bean's field, whereas <option> elements are created out of separate collection provided as model attribute.

Spring 4 Attribute 'items' must be an array, a Collection or a Map

i have this error when create a Combobox item in Spring 4.
java.lang.IllegalArgumentException: Attribute 'items' must be an array, a Collection or a Map
org.springframework.web.servlet.tags.form.AbstractMultiCheckedElementTag.writeTagContent(AbstractMultiCheckedElementTag.java:234)
org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:84)
...
I have POJO Class Student :
public class Student {
#Size(min=3, max=30)
private String firstName;
#Size(min=3, max=30)
private String lastName;
#NotEmpty
private String sex;
#DateTimeFormat(pattern = "dd/MM/yyyy")
#Past #NotNull
private Date dob;
#Email #NotEmpty
private String email;
#NotEmpty
private String section;
#NotEmpty
private String country;
private boolean firstAttempt;
#NotEmpty
private List<String> subjects = new ArrayList<String>();
...
I create method in my Controller and Annotate it with #ModelAttribute
#ModelAttribute("sections")
public List<String> initializeSections() {
List<String> sections = new ArrayList<String>();
sections.add("Graduate");
sections.add("Post Graduate");
sections.add("Research");
return sections;
}
Here is my JSP :
...
<div class="row">
<div class="form-group col-xs-12">
<label class="col-xs-3" for="section">Section</label>
<div class="col-xs-7">
<form:radiobuttons path="section" items="${sections}"/>
<div class="has-error">
<form:errors path="section" class="help-inline" />
</div>
</div>
</div>
</div>
...
When i run, i get above Error message.
How to fix that? What is missing?
Answer ✓
I missing one thing, i have to add this isELIgnored="false", i found
this according instruction from #JB Nizet to print out my EL. If you
create webapp project from Maven, you must declare isELIgnored="false" manually.
Thank you.
You are trying to generate multiple radio buttons, and the values at runtime.
Modify controller code as follows and try.
#ModelAttribute("sections")
public Map<String, List<String>> initializeSections() {
List<String> sections = new ArrayList<String>();
sections.add("Graduate");
sections.add("Post Graduate");
sections.add("Research");
Map<String, List<String>> sectionData = new HashMap<>();
sectionData.put("sections", sections);
return sectionData;
}
<%# page isELIgnored="false" %>
Include the above statement at the top of your jsp file

Iterate through a List property of an object with Struts2

Considering the following:
public class Company {
private String name;
private List<Person> employees;
//getters and setters
}
public class Person {
private String name;
private List<Car> cars;
//getters and setters
}
public class Car {
private String color;
//getter and setter
}
I want to get with Struts2 the color property of every car for every employee. So how would I iterate over the list of cars of every employee of the Company object?
After creating it, I put employees as employeeList into session. Using the following method, I can only get the name property, but can't iterate over the cars property:
<s:if test="#session.employeeList.size() > 0">
<s:iterator value="#session.employeeList">
<s:property value="name" /> //this works
<s:property value="cars" /> //how do I iterate over this list?
</s:iterator>
</s:if>
Doing this, the output for "cars" property is ognl.NoConversionPossible
I tried something like:
<s:if test="#session.employeeList.size() > 0">
<s:iterator value="#session.employeeList">
<s:property value="name" /> //this works
<s:iterator value="cars">
<s:property value="color" />
</s:iterator>
</s:iterator>
</s:if>
but doesn't work that way. Any ideas?
LE: Solution: Actually the iteration works. The objects I was talking about are mapped as Hibernate Entities. The "List cars" property is in fact a #ManyToMany relationship. So, after looking deeper into the error logs I found out that the cars property that I was trying to iterate was not being populated because Hibernate was lazily initializing it by default. I changed the FetchType to EAGER and the problem was solved.
The fact that I use session over the action attributes is not really important. Though, how could I use action attributes in this case? It doesn't seem doable.
Why not ?
Action:
public class MyAction extends ActionSupport {
private Company company; // private attribute
public Company getCompany(){ // public getter
return company;
}
public String execute(){
company = someService.loadTheCompanySomehow();
return SUCCESS;
}
}
JSP:
<s:iterator value="company.employees">
<s:property value="name" />
<s:iterator value="cars">
<s:property value="color" />
</s:iterator>
</s:iterator>
If the inner iteration doesn't work, there is probably something you have not shown to us, or related to the way you've cleaned the code before posting it.

Creating drop down list using Spring, Hibernate, JSP

Applications: Hibernate, Spring 3.0 MVC, JSP (used Spring forms)
Requirement: To select a table data from the database using Hibernate and display that as a drop-down list in JSP page using Spring MVC.
Code:
Hibernate / Dao code is
Cuisine class
#Entity
#Table(name = "cuisine")
public class Cuisine {
#Id
#Column(name = "id")
private int id;
#Column(name = "name")
private String name;
.. getters and setters
RecipeDaoImpl class
public List<Cuisine> getCuisine() {
String hql = "SELECT id, name FROM Cuisine";
return getSession().createQuery(hql).list();
}
Spring MVC
#Controller
public class RecipeController {
...
#RequestMapping("/add")
public String newRecipe(Map<String, Object> map) {
/* Get cuisine list and new object for cuisine */
List<Cuisine> cuisines = recipeServices.getCuisine();
System.out.println(cuisines);
map.put("cuisineList", cuisines);
map.put("cuisine", new Cuisine());
return "recipes/new";
}
JSP page:
<%# taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>
<tr>
<th><sf:label path="cuisine">Cuisine</sf:label></th>
</tr>
<tr>
<td><sf:select path="${cuisineList}">
<sf:options items="${cuisine}"></sf:options>
</sf:select></td>
</tr>
On doing it, I am getting following error:
org.springframework.beans.NotReadablePropertyException: Invalid property '[Cuisine [id=1, name=Continental][id=2, name=Italian]' of bean class [com.recipe.tables.Recipe]: Bean property '[Cuisine [id=1, name=Continental][id=2, name=Italian]' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:729)
org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:721)
org.springframework.validation.AbstractPropertyBindingResult.getActualFieldValue(AbstractPropertyBindingResult.java:99)
org.springframework.validation.AbstractBindingResult.getFieldValue(AbstractBindingResult.java:219)
org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:120)
Can someone please suggest how to fix this? I have checked couple of articles and tried to replicate them, but no luck.
I think jsp should be
<td><sf:select path="${cuisine}">
<sf:options items="${cuisineList}" id="id" itemValue="name"></sf:options>
</sf:select></td>
</tr>

How to save multiple identical entities from one form in Spring Controller?

I have a question, how to save multiple identical entities from one form in Spring Controller?
If I have the following code in html:
<form method="post" action="/dictionary/save">
<table>
... BEGIN jsp foreach function ...
<tr>
<td><input type=hidden name="id" value="${entity.id}"></td>
<td><input type=text name="en" value="${entity.en}"></td>
<td><input type=text name="lv" value="${entity.lv}"></td>
<td><input type=text name="ru" value="${entity.ru}"></td>
</tr>
... END jsp foreach function ...
</table>
<input type=submit value="Save">
</form>
In JSP listing can be till 50 entities. How to save its all in one request?
Create a modelAttribute of a domain object say .. dictionary which would have a list of some element (that you say can be 50 in the JSP)
in the JSP, use the modelAttribute in the form:form tag
and instead of input type use:
In Spring
class Dictionary{
#Id #GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(unique = true, nullable = false)
private String code;
#Column
private String ru;
#Column
private String lv;
#Column
private String en;
}
In Controller
List<Dictionary> diction=new ArrayList<Dictionary>();
model.addattribute("dictionary",diction);
In JSP
<form:form method="post" action="/dictionary/save" modelAttribute="dictionary">
<table><tr>
<td>
<form:input path="diction["+rowNum+"].code" />
<form:input path="diction["+rowNum+"].ru" />
<form:input path="diction["+rowNum+"].lv" />
<form:input path="diction["+rowNum+"].en" />
</td>
//code to add next td (either through javascript or jquery)
</form:form>
*Please see that
1. tags wont work in javascript or jquery and you can have simple input tags as *
<input type="text" name="code"/>
This name input could be as many as you want

Categories