在使用Spring MVC和Hibernate更新之前,如何预填充对象? [英] How to prepopulate an object before updating using spring mvc and hibernate?
问题描述
在用休眠保存该对象之前预填充对象的最佳实践是什么?
我做了什么:
我的控制器:
//The Form
@RequestMapping(value = "user/{id}/edit", method = RequestMethod.GET)
public String edit(@PathVariable("id") Long userId, ModelMap modelMap) {
modelMap.addAttribute("user", userService.find(userId));
return "user/userEdit";
}
//Updating database
@RequestMapping(value = "user/edit", method = RequestMethod.POST)
public String update(@ModelAttribute("user") @Valid User user, BindingResult result,
RedirectAttributes redirectAttrs) {
if (result.hasErrors()) {
return "user/userEdit";
}else{
userService.update(user);
redirectAttrs.addFlashAttribute("message", "Success");
return "redirect:user/userEdit";
}
}
如果我创建一个包含所有字段(用户名,密码和ID)的表单,它会起作用,但是如果我希望用户仅更新密码,该怎么办?
由于我在用户名处使用@NotEmpty,因此我收到一个错误,提示用户名为null,因为它的格式不是,但我不想输入用户名字段,而只输入密码.
我的html表单:
<c:url var="url" value="/user/edit" />
<form:form method="post" action="${url}" modelAttribute="user" class="form-horizontal">
<form:hidden path="id"/>
<form:hidden path="version"/>
<fieldset>
<div class="control-group">
<form:label cssClass="control-label" path="password"><spring:message code="user.label.password"/>: </form:label>
<div class="controls">
<form:input cssClass="input-xlarge" path="password" />
</div>
<form:errors path="password"/>
</div>
<div class="control-group">
<form:label cssClass="control-label" path="userRole"><spring:message code="user.label.role"/>: </form:label>
<div class="controls">
<form:select path="userRole">
<form:options items="${userRoleList}" itemValue="id" itemLabel="name"/>
</form:select>
</div>
<form:errors path="userRole"/>
</div>
<div class="control-group">
<form:label cssClass="control-label" path="costumer.id"><spring:message code="user.label.costumer"/>: </form:label>
<div class="controls">
<form:select path="costumer.id">
<form:options items="${costumerList}" itemValue="id" itemLabel="name"/>
</form:select>
</div>
<form:errors path="costumer.id"/>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Save changes</button>
<a class="btn cancel link" href="<c:url value="/user" />">Cancel</a>
</div>
</fieldset>
</form:form>
- 我尝试使用@Sessionattributes,但是如果我尝试使用@Sessionattributes,它将无法正常工作 使用浏览器标签编辑两个或多个用户.
- 我尝试使用属性编辑器,但未与@ModelAtrribute一起使用 用户用户.
- 我尝试使用转换器,但没有用.
唯一的方法是首先使User用户= userService.find(id),然后设置更新的值吗?像这样:
@RequestMapping(value = "user/edit", method = RequestMethod.POST)
public String update(@RequestParam("password") String password, BindingResult result, RedirectAttributes redirectAttrs) {
User user = userService.find(id);
if (password == null{
return "user/userEdit";
}else{
user.setPassword("password");
userService.update(user);
redirectAttrs.addFlashAttribute("message", "Success");
return "redirect:user/userEdit";
}
}
这是错误的,因为没有验证.
例如,我认为不太杂乱且不易出事的另一种方法是创建一个对UI表单进行建模的类
public class EditUserForm {
// getters and setters for password and other fields...
}
并在控制器的update(EditUserForm,...)
方法中,只需将用户在EditUserForm
中填充的所有字段映射到要更新的User
实例.
What's the best practice to pre-populate an object before saving this object with hibernate?
What i've done:
My controller:
//The Form
@RequestMapping(value = "user/{id}/edit", method = RequestMethod.GET)
public String edit(@PathVariable("id") Long userId, ModelMap modelMap) {
modelMap.addAttribute("user", userService.find(userId));
return "user/userEdit";
}
//Updating database
@RequestMapping(value = "user/edit", method = RequestMethod.POST)
public String update(@ModelAttribute("user") @Valid User user, BindingResult result,
RedirectAttributes redirectAttrs) {
if (result.hasErrors()) {
return "user/userEdit";
}else{
userService.update(user);
redirectAttrs.addFlashAttribute("message", "Success");
return "redirect:user/userEdit";
}
}
It works if i make a form containing all fields (username, password and id) , but what should i do if i want the user to update only the password?
Since i have a @NotEmpty at username, i get an error that username is null, since its not in the form, but i dont want to put the username field, just the password.
My html form:
<c:url var="url" value="/user/edit" />
<form:form method="post" action="${url}" modelAttribute="user" class="form-horizontal">
<form:hidden path="id"/>
<form:hidden path="version"/>
<fieldset>
<div class="control-group">
<form:label cssClass="control-label" path="password"><spring:message code="user.label.password"/>: </form:label>
<div class="controls">
<form:input cssClass="input-xlarge" path="password" />
</div>
<form:errors path="password"/>
</div>
<div class="control-group">
<form:label cssClass="control-label" path="userRole"><spring:message code="user.label.role"/>: </form:label>
<div class="controls">
<form:select path="userRole">
<form:options items="${userRoleList}" itemValue="id" itemLabel="name"/>
</form:select>
</div>
<form:errors path="userRole"/>
</div>
<div class="control-group">
<form:label cssClass="control-label" path="costumer.id"><spring:message code="user.label.costumer"/>: </form:label>
<div class="controls">
<form:select path="costumer.id">
<form:options items="${costumerList}" itemValue="id" itemLabel="name"/>
</form:select>
</div>
<form:errors path="costumer.id"/>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Save changes</button>
<a class="btn cancel link" href="<c:url value="/user" />">Cancel</a>
</div>
</fieldset>
</form:form>
- I tried using @Sessionattributes, but it doesnt work well if i try to edit two or more users using browser tabs.
- I tried using property editors, but didnt work with @ModelAtrribute User user.
- I tried using convertors but didnt work.
Is the only way to make a User user = userService.find(id) first, and then set the updated values? Something like:
@RequestMapping(value = "user/edit", method = RequestMethod.POST)
public String update(@RequestParam("password") String password, BindingResult result, RedirectAttributes redirectAttrs) {
User user = userService.find(id);
if (password == null{
return "user/userEdit";
}else{
user.setPassword("password");
userService.update(user);
redirectAttrs.addFlashAttribute("message", "Success");
return "redirect:user/userEdit";
}
}
Which seens wrong, because there is no validation.
An alternate way, that I think is less messy and accident-prone, is to create a class that models the UI form, for example
public class EditUserForm {
// getters and setters for password and other fields...
}
and in the controller's update(EditUserForm,...)
method, you simply map any fields populated by the user in the EditUserForm
to the instance of User
you wish to update.
这篇关于在使用Spring MVC和Hibernate更新之前,如何预填充对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!