Spring MVC passes ArrayList back to controller

I am new to Spring. I am showing a list with users. Each line has a flag for deleting users.

Controller:

@Controller public class AdminController { @Autowired private UserDao userDao; @RequestMapping(value = "/admin", method = RequestMethod.GET) public ModelAndView adminPage() { ModelAndView model = new ModelAndView(); model.addObject("users", userDao.findAll()); model.setViewName("admin"); return model; } @RequestMapping(value = "admin/remove", method = RequestMethod.POST) public ModelAndView removeUser(@ModelAttribute(value = "users") ArrayList<User> users) { ModelAndView model = new ModelAndView(); //UPDATE USERS HERE model.setViewName("redirect:/admin"); return model; } 

JSP:

 <form:form action="/admin/remove" method="POST" modelAttribute="users"> <table class="table table-striped"> <thead> <tr> <th>Firstname</th> <th>Lastname</th> <th>Email/login</th> <th>Profession</th> <th>Select<th> </tr> </thead> <tbody> <c:forEach var="user" items="${users}"> <tr> <td>${user.firstName}</td> <td>${user.lastName}</td> <td>${user.login}</td> <td>${user.profession}</td> <td><input type="checkbox" value="${user.delete}"/></td> </tr> </c:forEach> </tbody> </table> <input type="submit" value="Delete user(s)" class="btn-danger" /> <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> </form:form> 

The list is displayed correctly. If I click the "Delete Users" button. @ModelAttribute users are empty. I also tried to wrap the list in a new class, but I get the same results.

Any ideas?

+7
java spring spring-mvc jsp
source share
4 answers

Your ModelAttribute attribute is empty because the binding of form data does not come from your jsp to the model attribute. See how the Spring sample for binding collections is " http://developer.ucsd.edu/develop/user-interface/building-a-form/form-binding-with-collections.html ". This will help you understand.

Most Spring applications typically use a form: input with the path parameter to bind data.

+3
source share

Thanks to the minion, I found the answer

Packing:

 public class UserListWrapper { private ArrayList<User> users; public ArrayList<User> getUsers() { return users; } public void setUsers(ArrayList<User> users) { this.users = users; } 

Controller:

 @Controller public class AdminController { @Autowired private UserDao userDao; @RequestMapping(value = "/admin", method = RequestMethod.GET) public ModelAndView adminPage() { ModelAndView model = new ModelAndView(); UserListWrapper wrapper = new UserListWrapper(); wrapper.setUsers(new ArrayList<User>(userDao.findAll())); model.addObject("userListWrapper",wrapper); model.setViewName("admin"); return model; } @RequestMapping(value = "admin/remove", method = RequestMethod.POST) public ModelAndView removeUser(@ModelAttribute(value = "userListWrapper") UserListWrapper userListWrapper) { ModelAndView model = new ModelAndView(); userDao.removeFlaggedUsers(userListWrapper.getUsers()); model.setViewName("redirect:/admin"); return model; } 

}

View:

 <form:form action="/admin/remove" method="POST" modelAttribute="userListWrapper"> <table class="table table-striped"> <thead> <tr> <th>First name</th> <th>Last name</th> <th>Email/login</th> <th>Profession</th> <th>Select<th> </tr> </thead> <tbody> <c:forEach varStatus="us" var="user" items="${userListWrapper.users}" > <tr> <td><form:input type="hidden" path="users[${us.index}].firstName"/>${user.firstName}</td> <td><form:input type="hidden" path="users[${us.index}].lastName"/> ${user.lastName}</td> <td><form:input type="hidden" path="users[${us.index}].login"/>${user.login}</td> <td><form:input type="hidden" path="users[${us.index}].profession"/>${user.profession}</td> <td><form:checkbox path="users[${us.index}].delete" value="${user.delete}"/></td> <form:input type="hidden" path="users[${us.index}].id"/> </tr> </c:forEach> </tbody> </table> <input type="submit" value="Delete user(s)" class="btn-danger" /> <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> </form:form> 

Thanks!

EDIT: Remember to also add fields that you are not showing.

For example:

If you do not add an identifier, your deletion will not work, because the identifier in the returned object of the user will be NULL.

+6
source share

You must create your functionality around the spring -mvc select tag. A few changes would be fine, though, push the list into the POJO class, for example.

 public class FormBean { private List<String> users; public FormBean() { } public List<String> getUsers() { return users; } public void setUsers(List<String> users) { this.users = users; } } 

change your mapping to

 @RequestMapping(value = "admin/remove", method = RequestMethod.POST) public ModelAndView removeUser(@ModelAttribute(value = "formBean") FormBean formBean) { 

finally change your c: forEach using the select springs tag, so something like

 <form:form action="/admin/remove" method="POST" modelAttribute="formBean"> ... <form:select path="users" items="${users}" multiple="true" /> ... </form> 
+1
source share
0
source share

All Articles