Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 844
Ryan Deery Avatar asked Mar 09 '13 16:03

Ryan Deery


3 Answers

@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);

}

like image 63
SaK Avatar answered Oct 18 '22 23:10

SaK


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

add @ModelAttribute before Member. Then this instance will have all the edits. so you don't need to set new values by request.getParameter. Just save this instance in DB.

like image 31
Anubhab Avatar answered Oct 18 '22 23:10

Anubhab



This may have to do with the form attribute :
enctype="multipart/form-data"

There are no error logs when multiple parts are not resolved in Spring (this is very tricky).
Spring cannot read multiple attachment parts in the POST request, and Spring does not update the model.

Please make sure that you have set the multipart resolver in the dispatcher servlet XML file.
dispatcher-servlet.xml:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

And also add the below dependency to your pom.
pom.xml:

<dependency>
  <groupId>commons-fileupload</groupId>
  <artifactId>commons-fileupload</artifactId>
  <version>1.3.2</version>
</dependency>
like image 1
Etienne Tonnelier Avatar answered Oct 18 '22 22:10

Etienne Tonnelier