Spring MVC - How do I update a model object's attributes using a controller method?

forms, java, jsp, spring, spring-mvc

Solution

@RequestMapping(value = "/members/edit/{id}", method = RequestMethod.POST)
public String updateMember(@PathVariable int id, 
    HttpServletRequest request,@ModelAttribute("member") Member member) {

//Hope your MemberService looks similar

public void edit(Member member) {
logger.debug("Editing existing member");

// Retrieve session from Hibernate, if you are using hibernate
Session session = sessionFactory.getCurrentSession();

// Retrieve existing member via id
Member existingMember = (Member) session.get(Member.class, member.getId());

// Assign updated values to this member
existingMember.setForeName(member.getForeName());
existingMember.setSurName(member.getSurName());
...
...
existingMember.setPostcode(member.getPostcode());

// Save updates
session.save(existingMember);

}

Problem

Using Spring MVC 3.0, I am developing a member management system with basic CRUD operations and am having trouble with my Controller. I cannot update a member record using a Controller method. I have methods to display and process my 'Add Member' form and another to display my 'Edit Member' form and they all work fine. Here is my controller: ``` @Controller public class MemberController { private MemberService memberService; @Inject public MemberController(MemberService memberService) { this.memberService = memberService; } // Show member list @RequestMapping(value = "/members/list", method = RequestMethod.GET) public String showMemberList(Map<String, Object> model) { model.put("members", memberService.getAllMembers()); return "members/list"; } // Display add member form @RequestMapping(value = "/members/add", method = RequestMethod.GET) public String showAddMemberForm(Model model) { model.addAttribute(new Member()); return "members/add"; } // Process add member form @RequestMapping(value = "/members/add", method = RequestMethod.POST) public String addMember(Member member) { memberService.addMember(member); return "redirect:list"; } // Display edit member form @RequestMapping(value = "/members/edit/{id}", method = RequestMethod.GET) public String showEditMemberForm(Model model, @PathVariable int id) { String idAsString = Integer.toString(id); model.addAttribute("member", memberService.getMemberById(idAsString)); return "members/edit/{id}"; } // Process edit member form @RequestMapping(value = "/members/edit/{id}", method = RequestMethod.POST) public String updateMember(@PathVariable int id, HttpServletRequest request, Member member) { // Uncommenting the next line of code sets the member objects forename attribute // to "test forename" // member.setForename("test forename"); // Uncommenting the next line of code gives the following error: // HTTP Status 405 - Request method 'POST' not supported //member.setSurname(request.getParameter("surname")); memberService.updateMember(member); return "redirect:/members/list"; } ``` } Here is my update method: ``` public void update(Member member) { jdbcTemplate.update( "UPDATE members SET forename=?, surname=?, address1=?, address1=?, " + "city=?, postcode=? WHERE memberId=?", member.getForename(), member.getSurname(), member.getAddress1(), member.getAddress2(), member.getCity(), member.getPostcode(), member.getId()); } ``` And here is my Edit Member JSP form: ``` <sf:form method="POST" modelAttribute="member" enctype="multipart/form-data" action="/members/edit/${member.id}"> <fieldset> <table cellspacing="0"> <tr> <th><label for="member_id">Id:</label></th> <td><sf:input path="id" size="15" id="member_id" /></td> </tr> <tr> <th><label for="member_forename">Forename:</label></th> <td><sf:input path="forename" size="15" id="member_forename" /></td> </tr> <tr> <th><label for="member_surname">Surname:</label></th> <td><sf:input path="surname" size="15" id="member_surname" /></td> </tr> <tr> <th><label for="member_address1">Address 1:</label></th> <td><sf:input path="address1" size="15" id="member_address1" /> </td> </tr> <tr> <th><label for="member_address2">Address 2:</label></th> <td><sf:input path="address2" size="15" id="member_address2" /> </td> </tr> <tr> <th><label for="member_city">City:</label></th> <td><sf:input path="city" size="15" id="member_city" /></td> </tr> <tr> <th><label for="member_postcode">Postcode:</label></th> <td><sf:input path="postcode" size="15" id="member_postcode" /> </td> </tr> </table> <input type="submit" value="Update" /> </fieldset> </sf:form> ``` Because the 'member.setForename("test forename")' code in my Controller sets the test string, I thought I could use the parameters that are posted from the form to set the atrributes as follows: 'member.setSurname(request.getParameter("surname"))' But this causes an HTTP 405 error. Using Firebug, I have confirmed that the 'Edit Member' form is posting the 'forename', 'surname', 'address1', etc. parameters so I can't figure out why I can't pull them off the request. Any help would be greatly appreciated as I have been at this for 2 days and am going round in circles.

Original source