34

Suppose I have class Person, I made a list of Person instances and add this list to a Model.

List<Person> persons = new ArrayList<Person>();
model.addAttribute("persons",persons);
return "savePersons";

In the View page I have a form:

<form:form method="post" action="savePerson" modelAttribute="persons">
    <c:forEach var="person" items="${persons}">
        <form:input path="person.FName" name="FName" id="FName" value="" />
        <form:input path="person.LName" name="LName" id="LName" value="" />
    </c:forEach>

    <button type="submit"></button>
</form:form>

When I click on the submit button I want to bind the Person List to the POST method on the controller..

@RequestMapping(value = { "savePerson" }, method = RequestMethod.POST)
public String savePerson(Model model, HttpServletRequest request,
        HttpSession session,@ModelAttribute("persons")List<Person> persons) {
    System.out.println(persons.length);
    return "success";
}

but the persons list is not binding/fetching at the POST method.

Is it possible to bind a list objects in this way or is there an alternative for this?

moffeltje
  • 4,521
  • 4
  • 33
  • 57
Amogh
  • 4,453
  • 11
  • 45
  • 106

2 Answers2

55

I think this link will help you set up what you are trying to do:

http://viralpatel.net/blogs/spring-mvc-multi-row-submit-java-list/

It looks like in your form you need to modify it to something like:

<form:form method="post" action="savePerson" modelAttribute="persons">
    <c:forEach var="person" items="${persons}" varStatus="status">
        <form:input path="person[${status.index}].FName" name="FName" id="FName" value="" />
        <form:input path="person[${status.index}].LName" name="LName" id="LName" value="" />
    </c:forEach>

This SO question has a pretty good example that might help you out too: List<Foo> as form backing object using spring 3 mvc, correct syntax?

Community
  • 1
  • 1
ssn771
  • 1,270
  • 2
  • 17
  • 20
  • Link suggested by @ssn771 is very nice and simple for understand.Thanks ssn771. – Amogh Mar 19 '13 at 07:05
  • 2
    Just wondering is it persons (with a s) for the form:input path statement? persons[${status.index}] – Maximus Jun 18 '14 at 19:44
  • 3
    But this gets failed if the list size is more than 256. – Shri Jun 26 '14 at 14:09
  • 1
    @Shri, Sorry for late reply I don't know whether you solved error or not but you have to write code at controller in `init()` to avoid this. – Amogh Jul 10 '14 at 19:00
  • @Amogh What to write in init(), which part of the code you are talking about,. – Shri Jul 11 '14 at 10:45
  • @Shri, Answer is added for that code. sorry I mentioned init() in my comment actually it's `@initBinder` – Amogh Jul 11 '14 at 13:34
  • 1
    I agree with @Maximus - paths should be to `persons[${status....` not `person[${status...`. – vegemite4me Nov 11 '15 at 12:13
  • The Viralpatel link : this is causing null pointer exception at controller Check this question: http://stackoverflow.com/questions/35764487/list-of-object-is-not-going-in-post-request – Sai prateek Mar 03 '16 at 09:37
  • Can someone please explain to me why do I get this explicit url after submiting the form : saveUrl?objects[0].attribute1=value&objects[0].attribute2=value&objects[0].attribute3=value&objects[1].attribute1=value&objects[1].attribute2=value&objects[1].attribute3=value .. etc and the endpoint isn't called in the end – Ammar Akouri Jan 12 '21 at 16:20
22

As Shri mentioned in his comment on ssn771 answer that if your binding list is more then 256 then it gives error like

org.springframework.beans.InvalidPropertyException : Invalid property 'mylist[256]' of bean class [com.app.MyPageListVO]: Index of out of bounds in property path 'mylist[256]'; nested exception is java.lang.IndexOutOfBoundsException: Index: 256, Size: 256 at org.springframework.beans.BeanWrapperImpl.getPrope rtyValue(BeanWrapperImpl.java:830) at...

This error occurs because by default 256 is limit for array and collection auto-growing to avoid OutOfMemoryErrors, But you can increase this limit by setting WebDataBinder's AutoGrowCollectionLimit property in @InitBinder in that controller.

Code:

@InitBinder
public void initBinder(WebDataBinder dataBinder) {
    // this will allow 500 size of array.
    dataBinder.setAutoGrowCollectionLimit(500);
}
Community
  • 1
  • 1
Amogh
  • 4,453
  • 11
  • 45
  • 106