Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MVC passing ArrayList back to controller

I am new to Spring. I display a list with users. Every row has a checkbox for removing the 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 rendered correctly. If i press the "Delete user(s)" button. The @modelAttribute users is empty. I also tried wrapping the list in a new class, but i get the same results.

Any ideas?

like image 444
user1449511 Avatar asked Feb 19 '15 14:02

user1449511


2 Answers

Thanks to minion, i found the answer

Wrapper:

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>

Thank you!

EDIT: Dont forget to also add the fields you are not displaying.

For example:

If you dont add the id, your delete will not work because the id in the returned User object will be NULL.

like image 200
user1449511 Avatar answered Nov 05 '22 05:11

user1449511


Your ModelAttribute is empty as there is no form data binding happening from your jsp to your model attribute. Take a look at how Spring sample for binding collections "http://developer.ucsd.edu/develop/user-interface/building-a-form/form-binding-with-collections.html". This will help you to understand.

Most of the Spring application typically uses form:input with "path" parameter to do data binding.

like image 41
minion Avatar answered Nov 05 '22 05:11

minion