我正在使用Spring Roo
创建一个带有用户管理的简单Web应用程序。我有一个AppUser
实体,其中包含password
字段,当更新实体的其他属性时,即使我没有更改它,也会将其设置为null。
为了实现更新AppUser
实例的用例,Roo
生成了两种方法updateForm
和update
。
前一种方法准备用于编辑实体的表单:
@RequestMapping(value = "/{id}", params = "form", produces = "text/html")
public String updateForm(@PathVariable("id") Long id, Model uiModel) {
AppUser appUser = AppUser.findAppUser(id);
populateEditForm(uiModel, appUser);
System.out.println("On Update Form - " + appUser);
return "users/update";
}
第二种方法检查验证错误并将实体合并到JPA上下文中:
@RequestMapping(method = RequestMethod.PUT, produces = "text/html")
public String update(@Valid AppUser appUser, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) {
System.out.println("On Update - " + appUser);
if (bindingResult.hasErrors()) {
populateEditForm(uiModel, appUser);
return "users/update";
}
uiModel.asMap().clear();
appUser.merge();
return "redirect:/users/" + encodeUrlPathSegment(appUser.getId().toString(), httpServletRequest);
}
编辑表单中password
字段的默认值为空,但是在它的mutator方法setPassword
上,当发送null或空白时,我没有更新密码。
public void setPassword(String password) {
// Don't update password if null or blank is sent
if (password != null && !password.isEmpty()) {
String encodedPassword = passwordEncoder.encodePassword(password, null);
this.password = encodedPassword;
}
}
标准输出的结果如下:
On Update Form - AppUser[username=user,password=04f8996da763b7a969b1028ee3007569eaf3a635486ddab211d512c85b9df8fb,enabled=true,appRole=AppRole[rolename=ROLE_USER,id=2,version=1],customer=Customer[code=<null>,description=default,address=<null>,cap=<null>,locality=<null>,province=<null>,telephone=<null>,fax=<null>,vat=<null>,fiscalCode=<null>,sex=<null>,customerType=<null>,insertionDate=<null>,lastVisit=<null>,id=0,version=<null>],id=2,version=0]
On Update - AppUser[username=user,password=<null>,enabled=true,appRole=AppRole[rolename=ROLE_USER,id=2,version=1],customer=Customer[code=<null>,description=default,address=<null>,cap=<null>,locality=<null>,province=<null>,telephone=<null>,fax=<null>,vat=<null>,fiscalCode=<null>,sex=<null>,customerType=<null>,insertionDate=<null>,lastVisit=<null>,id=0,version=<null>],id=2,version=0]
显然密码正在改变,但我无法理解在哪里。
修改
我用来更新AppUser信息的jspx视图如下:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:field="urn:jsptagdir:/WEB-INF/tags/form/fields" xmlns:form="urn:jsptagdir:/WEB-INF/tags/form" xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
<jsp:directive.page contentType="text/html;charset=UTF-8"/>
<jsp:output omit-xml-declaration="yes"/>
<form:update id="fu_it_digitelematica_leovince_domain_AppUser" modelAttribute="appUser" path="/users" versionField="Version" z="9/aOTZ+wTF1ijLMgiWkx1JcbpG8=">
<field:input field="username" id="c_it_digitelematica_leovince_domain_AppUser_username" required="true" z="H3JOKuXes6/RLOnAd4x1v0j3Njo="/>
<field:input field="password" id="c_it_digitelematica_leovince_domain_AppUser_password" required="false" type="password" z="user-managed"/>
<field:checkbox field="enabled" id="c_it_digitelematica_leovince_domain_AppUser_enabled" z="4WIlYpFXs46FLp4l8koJ2DXmWz8="/>
<field:select field="appRole" id="c_it_digitelematica_leovince_domain_AppUser_appRole" itemValue="id" items="${approles}" path="/approles" required="true" z="KDeZRlxip/VWLtb/kN58hn2zZdg="/>
<field:select field="customer" id="c_it_digitelematica_leovince_domain_AppUser_customer" itemValue="id" items="${customers}" path="/customers" required="true" z="rEMR1CzjRLuSkoIKTHmq4N+qZoI="/>
</form:update>
</div>
答案 0 :(得分:0)
您是否尝试删除&#34; type = password&#34;来自你的领域的属性:输入?
也许,input.tagx上有一个错误......你能试试吗?
如果您检测到错误,则可以在http://jira.spring.io/browse/ROO
上创建问题答案 1 :(得分:0)
这是标准方式:合并实体时,覆盖其所有值。让我解释一下:
在第2点 entityManager 对提交及其值不了解,因此,当您合并用户时,如果password
字段为null
,则该字段将为DB上的字段的新值。这就是为什么Spring Roo生成的视图包含更新形式的所有字段。
要解决此问题,您必须加载附加的实体实例,并填写绑定实例的缺失值(警告,未测试代码 ):
@RequestMapping(method = RequestMethod.PUT, produces = "text/html")
public String update(@Valid AppUser appUser, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) {
System.out.println("On Update - " + appUser);
if (bindingResult.hasErrors()) {
populateEditForm(uiModel, appUser);
return "users/update";
}
uiModel.asMap().clear();
User attached = User.findUserById(user.getId());
appUser.setPassword_encoded(attached..getPassword());
appUser.merge();
return "redirect:/users/" + encodeUrlPathSegment(appUser.getId().toString(), httpServletRequest);
}
你需要一个设置密码而不编码的mutator。
祝你好运!