【问题标题】:Update object using JSP form使用 JSP 表单更新对象
【发布时间】:2015-11-16 17:57:00
【问题描述】:

如果我将一个对象传递给 jsp 页面,如何使用 setter 更新其字段并将其发送回?

如果我们有

public class Person {

    private int age;
    private String name;

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }
}

还有一个控制器

@RequestMapping(value = "/updatePerson", method = RequestMethod.GET)
public String showPerson(Model model) {
    Person person = new Person();
    person.setAge(23);
    person.setName("Jack");
    model.addAttribute("person", person);

    return "updatePerson";
}

还有一个jsp页面

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

<form:form modelAttribute="person">
    <form:input path="age"/>
    <input type="submit"/>
</form:form>

如何让这个 JSP 页面作为结果发送修改过的 person 对象,而不是只有一个字段的新对象?

【问题讨论】:

  • 要发送一个新的修改对象,你需要一个新的对象处理程序,最好配置为接受一个表单方法。
  • @nikpon 没看懂,能给个链接例子吗

标签: java spring jsp spring-mvc


【解决方案1】:

在控制器中添加一个处理表单提交的方法:

@RequestMapping(value = "/updatePerson", method = RequestMethod.POST)
public String alterPerson(@ModelAttribute Person person) {
    // do stuff
}

注意变化:

  • POST 而不是GET:提交表单默认使用POST-Requests。
  • @ModelAttribute 自动检索提交的数据并用它填充一个Person 对象

不过,对于您拥有的表单,name 字段将始终为空。添加另一个&lt;form:input path="name"/&gt; 来解决这个问题。

如果您不想让用户更改他们的名字,Person 对象可能根本不应该在您的模型中;不过,这取决于这些对象的持久化方式。你可以像这样使用一个单独的对象:

public class PersonChangeRequest {
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

并将其用作@ModelAttribute,如下所示:

@RequestMapping(value = "/updatePerson", method = RequestMethod.GET)
public String showPerson(Model model) {
    PersonChangeRequest person = new PersonChangeRequest();
    person.setAge(23);
    model.addAttribute("person", person);

    return "updatePerson";
}

@RequestMapping(value = "/updatePerson", method = RequestMethod.POST)
public String alterPerson(@ModelAttribute PersonChangeRequest personChangeRequest) {
    Person person = findPersonToChange(personChangeRequest);
    person.setAge(personChangeRequest.getAge());
}

【讨论】:

  • 问题是我不希望允许某人更改他的名字。我只需要显示一个字段。当然可以隐藏(使用 style 属性 display: none),但我认为这不是最好的解决方案。
  • 然后你需要另一个对象,比如PersonChangeRequestAgeChangeRequest,它只有一个年龄字段,在你的模型中;您收到该对象,对其进行验证,最后使用新值更新底层 Person。当前的设置方式,攻击者可以在 POST-Request 中添加名称,Person 的名称将被更改。没有name 的输入字段并不能阻止这一点。
  • 我认为这是唯一的解决方案。如果您发布它,我会将其标记为正确
  • @a76 我已将其添加到我的帖子中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-05
  • 1970-01-01
  • 1970-01-01
  • 2017-09-12
相关资源
最近更新 更多