我在JBoss 7.2上托管的Spring MVC 4.0.6遇到了一个非常奇怪的问题。更新现有用户时,提交的信息有时会转移到POST RequestMapping控制器方法(下面的validateUpdate方法)。
UserController.java
@Controller
@RequestMapping(value = "/security/user")
@SessionAttributes(value = {"userForm", "user"})
public class UserController {
private final String CREATE_VIEW = "user/createOrUpdate";
private final String READ_VIEW = "user/readOrDelete";
private final String UPDATE_VIEW = CREATE_VIEW;
private final String DELETE_VIEW = READ_VIEW;
@Autowired
private LocationService locationService;
@Autowired
private SecurityService securityService;
@Autowired
private UserValidator userValidator;
@InitBinder("userForm")
protected void initBinder(WebDataBinder binder) {
binder.setValidator(userValidator);
binder.setDisallowedFields("strId");
}
@ModelAttribute("regions")
public List<Region> populateRegions() {
Locale locale = LocaleContextHolder.getLocale();
List<Region> regions = this.locationService.lstRegions(locale.getLanguage());
return regions;
}
@RequestMapping(value = "/update/{intUserId}", method = RequestMethod.GET)
public String updateUser(@PathVariable Integer intUserId, Model model) {
User user = this.securityService.findUserByPk(intUserId);
if (user != null) {
UserForm userForm = new UserForm();
userForm.setUser(user);
model.addAttribute(userForm);
}
return UPDATE_VIEW;
}
@RequestMapping(value = "/update/validate", method = RequestMethod.POST)
public String validateUpdate(@Valid @ModelAttribute("userForm") UserForm userForm,
BindingResult result,
Model model,
RedirectAttributes redirectAttributes,
SessionStatus status) {
return this.performCreateOrUpdateOperation(userForm, result, model, redirectAttributes, status);
}
private String performCreateOrUpdateOperation(
UserForm userForm,
BindingResult result,
Model model,
SessionStatus status) {
if(result.hasErrors()) {
return UPDATE_VIEW;
} else {
User user = userForm.getUser();
this.securityService.validateCreateOrUpdateUser(result, user);
if (result.hasErrors() == false) {
if (userForm.isNew()) {
this.securityService.addUser(user);
} else {
this.securityService.updateUser(user);
}
model.addAttribute(user);
status.setComplete();
return "user/success";
} else {
return UPDATE_VIEW;
}
}
}
}
表单Bean
public class UserForm {
private String strUserIdToSearch = "";
private String strId = "0";
private String strUserId = "";
private String strFirstName = "";
private String strLastName = "";
private String strEmail = "";
private String strRegionId = "0";
private boolean booArchived = false;
public User getUser() {
User user = new User();
user.setIntId(Integer.valueOf(this.strId));
user.setStrUserId(this.strUserId);
user.setStrFirstName(this.strFirstName);
user.setStrLastName(this.strLastName);
user.setStrEmail(this.strEmail);
Region region = new Region(Integer.valueOf(this.strRegionId));
user.setRegion(region);
user.setBooArchived(this.booArchived);
return user;
}
public void setUser(User user) {
this.strUserIdToSearch = user.getStrUserId();
this.strId = String.valueOf(user.getIntId());
this.strUserId = user.getStrUserId();
this.strFirstName = user.getStrFirstName();
this.strLastName = user.getStrLastName();
this.strEmail = user.getStrEmail();
this.strRegionId = String.valueOf(user.getRegion().getIntId());
this.booArchived = user.getBooArchived();
}
...getters and setters...
}
JSP(为清晰起见,删除了样式) crudMethod是一个JSP标签返回&#34;创建&#34;,&#34;读&#34;,&#34;更新&#34;或&#34;删除&#34;取决于$ {requestScope [&#39; javax.servlet.forward.request_uri&#39;]}
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<spring:url var="userFormAction" value="/rest/security/user/${crudMethod}/validate" />
<form:form id="userForm" modelAttribute="userForm" action="${userFormAction}" method="POST">
<form:hidden path="strId" />
<form:hidden path="strUserId" id="strUserId" />
<form:hidden path="strLastName" id="strLastName" />
<form:hidden path="strFirstName" id="strFirstName" />
<form:hidden path="strEmail" id="strEmail" />
<form:select id="strRegionId" path="strRegionId">
<form:option value="0" label="${strSelectRegionLabel}" />
<form:options items="${regions}" itemValue="intId" itemLabel="${strRegionLabel}" />
</form:select>
</form:form>
因此,当我提交表单时,例如,将区域更改为列表中的另一个ID(让我们说从1到6)。有时它有效,有时不行。通过&#34;工作&#34;,我的意思是我点击成功页面,然后我回去再次看到用户。有时它会保持在1,有时它会变为6.
我找到了一个模式/解决方法,可以一直重现问题:
问题是:为什么?我错过了什么吗?
注意:它与业务层无关。我测试了它,它很稳定。这肯定与我使用Spring MVC Framework有关。
浏览器是IE11。
感谢您的帮助。
*更新2015-06-29 *
经过几次搜索后,我发现:
请求邮件正文总是正确的,如下所示:
strId = THE_ID&安培; strUserId = THE_USERID&安培; strLastName = THE_LASTNAME&安培; strFirstName = THE_FIRSTNAME&安培; strEmail = THE_EMAILADDRESS&安培; strRegionId = THE_REGIONID&安培; booArchived =假
请注意&#34; THE_REGIONID&#34;每次都很好。
相关资源
答案 0 :(得分:1)
Path.Combine
我认为表单中的 id :select 是罪魁祸首。它与 UserForm 中的属性名称不匹配,即&#34; strRegionId &#34;。因此它不会绑定。将ID值更改为 strRegionId