我明白@InitBinder用于安全方面的原因,但它引起了我的各种问题。
我有一个UserController的一个更新方法如下。
@Secured(value={"ROLE_ADMIN"})
@Transactional
@RequestMapping(value="/user/{id}", method=RequestMethod.PUT)
public String userUpdate(User user, BindingResult userBinding, Model model, @PathVariable long id) {
if (userBinding.hasErrors()) {
return (String.format("user/{%s}/edit", String.valueOf(user.getId())));
}
try {
userService.updateUser(user);
}
catch (Exception e) {
logger.error("Unable to update user", e);
}
return "redirect:/user";
}
而且我有这个是我的UserController的为好。
@InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
dataBinder.setDisallowedFields("id");
}
我的JSP来处理创建和更新如下。
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<div class="container">
<div class="row">
<div class="col-xs-12">
<spring:bind path="user.*">
<c:if test="${status.errors.errorCount > 0}">
<div class="alert alert-danger">
<p>Error: unable to save, please check the errors below</p>
</div>
</c:if>
</spring:bind>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-8 col-md-6">
<h3>User - Add</h3>
<br>
<c:choose>
<c:when test="${user.id > 0}">
<c:set var="formMethod" value="PUT" />
<c:url var="formAction" value="/user/${user.id}" />
</c:when>
<c:otherwise>
<c:set var="formMethod" value="POST" />
<c:url var="formAction" value="/user" />
</c:otherwise>
</c:choose>
<sf:form method="${formMethod}" action="${formAction}" commandName="user">
<spring:bind path="user.id">
<sf:hidden path="${status.expression}" id="user-id" />
</spring:bind>
<spring:bind path="user.firstName">
<div class="form-group">
<label for="first-name">First Name</label>
<sf:input path="${status.expression}" id="first-name" class="form-control" placeholder="First Name" />
<sf:errors path="${status.expression}" cssClass="error-message"></sf:errors>
</div>
</spring:bind>
<spring:bind path="user.lastName">
<div class="form-group">
<label for="last-name">Last Name</label>
<sf:input path="${status.expression}" id="last-name" class="form-control" placeholder="Last Name" />
<sf:errors path="${status.expression}" cssClass="error-message"></sf:errors>
</div>
</spring:bind>
<spring:bind path="user.email">
<div class="form-group">
<label for="email">Email</label>
<sf:input path="${status.expression}" id="email" class="form-control" placeholder="Email" />
<sf:errors path="${status.expression}" cssClass="error-message"></sf:errors>
</div>
</spring:bind>
<spring:bind path="user.username">
<div class="form-group">
<label for="user-name">Username</label>
<sf:input path="${status.expression}" id="user-name" class="form-control" placeholder="Username" />
<sf:errors path="${status.expression}" cssClass="error-message"></sf:errors>
</div>
</spring:bind>
<spring:bind path="user.password">
<div class="form-group">
<label for="password">Password</label>
<sf:password path="${status.expression}" id="password" class="form-control" placeholder="" />
<sf:errors path="${status.expression}" cssClass="error-message"></sf:errors>
</div>
</spring:bind>
<div class="form-group">
<label for="confirm-password">Confirm Password</label>
<input type="password" name="password-confirm" id="confirm-password" class="form-control" placeholder="" />
</div>
<spring:bind path="user.roleId">
<div class="form-group">
<label for="role">Role</label>
<sf:select path="${status.expression}" id="role" class="form-control" >
<sf:options items="${roles}" itemLabel="name" itemValue="id"/>
</sf:select>
<sf:errors path="${status.expression}" cssClass="error-message"></sf:errors>
</div>
</spring:bind>
<button type="submit" class="btn btn-default">Save</button>
<button type="button" class="btn btn-default">Cancel</button>
</sf:form>
</div>
</div>
</div>
到userService.update(用户)呼叫呼叫JPA合并方法。 它失败,因为它试图插入包含一个唯一约束,这是已经在数据库中的新纪录。 不用通过代码,互联网和堆栈跟踪挖了几个小时之后说,我意识到未来从JSP后面的ID为null。 有一次,我注释掉@InitBinder方法一切都开始正常工作。 这使我想起我的真正的问题,我需要为@InitBinder原因secuirty,如果是的话我怎么解决这个问题我刚才所描述的?