【问题标题】:Spring MVC - How do I update a model object's attributes using a controller method?Spring MVC - 如何使用控制器方法更新模型对象的属性?
【发布时间】:2013-02-25 03:16:27
【问题描述】:

使用 Spring MVC 3.0,我正在开发一个具有基本 CRUD 操作的成员管理系统,但我的控制器遇到了问题。

我无法使用 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";
}

}

这是我的更新方法:

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());
}

这是我的编辑成员 JSP 表单:

<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>

因为我的 Controller 中的 'member.setForename("test forename")' 代码设置了测试字符串,我想我可以使用从表单中发布的参数来设置属性,如下所示:

'member.setSurname(request.getParameter("surname"))'

但这会导致 HTTP 405 错误。使用 Firebug,我已经确认“编辑成员”表单正在发布“名字”、“姓氏”、“地址 1”等参数,所以我无法弄清楚为什么我不能将它们从请求中删除。

任何帮助都将不胜感激,因为我已经在此工作了 2 天,并且正在兜圈子。

【问题讨论】:

  • 如果我的回答有帮助,请告诉我..
  • 你能从 MemberService 类中粘贴你的编辑方法吗?让我们好好看看。
  • @Satish'SaK'Krishnamurthy 我已将我的编辑/更新方法添加到我的问题中。
  • 更新方法看起来不错。就在查询中,我看到您将 address1 设置了两次(可能是错字)。另见this FYR..
  • 那是地址1的错误我现在已经更正了谢谢。

标签: java forms spring jsp spring-mvc


【解决方案1】:
@RequestMapping(value = "/members/edit/{id}", method = RequestMethod.POST)
public String updateMember(@PathVariable int id, 
    HttpServletRequest request,@ModelAttribute("member") Member member) {

//希望您的 MemberService 看起来相似

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

}

【讨论】:

  • 我没有使用 Hibernate。抱歉,我无法理解该代码:(
【解决方案2】:
@RequestMapping(value = "/members/edit/{id}", method = RequestMethod.POST)
public String updateMember(@PathVariable int id, 
        HttpServletRequest request,@ModelAttribute("member") Member member) {

Member 之前添加@ModelAttribute。 然后这个实例将拥有所有的编辑。所以您不需要通过request.getParameter 设置新值。只需将此实例保存在数据库中即可。

【讨论】:

  • 我已经添加了@ModelAttribute 注释,它没有任何区别。提交编辑表单后,我将被重定向到成员列表,并且记录显示为空,除了成员 ID。
  • 您能否在更新数据库之前记录控制器内的值,以便您知道那里有哪些值?
  • 还在表单标签中添加commandName 属性以具有member 值。 commandName="member"
  • 请检查我在注释中添加("member") 的编辑
  • 我已经将commandName添加到表单和注释之后的(“member”),但仍然没有区别。我不确定我是否设置了日志记录,但我现在会检查。谢谢
【解决方案3】:

这可能与 form 属性有关:
enctype="multipart/form-data"

在 Spring 中未解析多个部分时没有错误日志(这很棘手)。
Spring 无法读取 POST 请求中的多个附件部分,并且 Spring 不会更新模型。

请确保您已在调度程序 servlet XML 文件中设置多部分解析器。
dispatcher-servlet.xml:

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

并将以下依赖项添加到您的 pom。
pom.xml:

<dependency>
  <groupId>commons-fileupload</groupId>
  <artifactId>commons-fileupload</artifactId>
  <version>1.3.2</version>
</dependency>

【讨论】:

  • 这解决了我的问题,当我的控制器从 Spring 3.2.5 迁移到 Spring 4.3.12 时停止工作,显然需要显式的 multipartResolver。我不知道这两个版本之间到底发生了什么变化。
猜你喜欢
  • 2019-01-08
  • 2019-11-01
  • 2013-08-07
  • 2016-11-09
  • 2019-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-03
相关资源
最近更新 更多