java使用Spring MVC 3+Hibernate更新持久化对象的“正确”或“安全”方法是什么?
给出一个非常简单的对象:
class User {
private Integer id;
private String name;
public User() {}
public Integer getId() { return id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
还有一个非常简单的控制器动作:
@RequestMapping(value="/edit/{id}/**", method=RequestMethod.POST)
public String editFromForm(@PathVariable("id") Integer id, @Valid User user, BindingResult bindingResult, Model model) {
// If we have errors, don't save
if(bindingResult.hasErrors()) {
// Put what they did in the model and send it back
model.addAttribute(user);
return "users/edit";
} else {
userDAO.save(user);
}
// Show them the updated page on success
return "redirect:/users/" + user.getId() + "/" + user.getName();
}
还有一个非常简单的形式:
<sf:form method="POST" modelAttribute="user">
<label for="user_name">Name:</label>
<sf:input path="name" id="user_name" />
<input type="submit" value="save" /><sf:errors path="name" cssClass="error" />
</sf:form>
我应该如何更新数据库中的实体?目前(由于saveOrUpdate()
是我的DAO的save()
方法后面的实际hibernate调用,因此会持久化一个新对象,而不是更新现有对象,因为没有在表单提交创建的对象上设置id
字段
我想到了几种可能的解决方案,但我不确定哪种方法在保持事物干净和安全方面是最好的(这样恶意用户就不能随心所欲地编辑任何对象Id)
- 将URL参数中的id插入模型绑定器中的对象
- 在表单中有一个隐藏的
id
字段,并让模型绑定器附加id
在这两种情况下,都没有检查来确保对象仍然是同一个对象,例如某种校验和。其他人如何应对?有没有明确的例子可以说明这个问题
出现的另一个问题是,由于Hibernate正在管理所有id,我不希望使用setId()
方法。根据我所能确定的,Spring MVC模型绑定器只能绑定一个字段,前提是它具有预期的getter和setter。是否有其他方法应用新状态,例如通过URL的id
参数从数据库获取当前用户,然后对其应用新状态,但不必显式地对所有字段副本进行编码
我相信有一个相当简单,直接的方法来处理这个问题,但我的大脑似乎无法想出一个合适的解决方案
我对Spring+Hibernate还比较陌生,所以请原谅我,如果这是一个平淡无奇、涉及面很广的话题,但我还没有找到任何明确的例子来说明我的简单情况。如果这在其他地方已经被充分地涵盖,请给我指出正确的方向
共 (0) 个答案