我是Spring和Java的新手,并致力于使用JSP,JSTL,Hibernate / JPA和模型类来获取Spring MVC中的表单。我可以让页面显示正常,但是应该创建用户的帖子给了我一个错误。
Failed to convert property value of type java.lang.String to required type com.everesttech.recruiting.searchtool.entity.Role for property user.role; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.everesttech.recruiting.searchtool.entity.Role] for property role: no matching editors or conversion strategy found
此错误有意义,因为表单正在传递Role的ID,而User对象需要传递Role对象。但是我不知道如何解决这个问题,同时仍然允许我的JSP由我的实际Entity对象支持,因为我想使用Spring / Hibernate验证。有没有办法声明该表单:选择作为角色对象?任何建议或解决方案都非常感谢。谢谢你提前。
我提供了项目中相关的代码部分。我没有包含来自我的服务层和实体层的代码,因为我知道它们正在工作。但是,如果需要,我也可以包括这些。用户与Role有多对一的关系。
UserController中
/**
* display the user add page
*
* @return returns the view name
*/
@RequestMapping(value="/user/add", method=RequestMethod.GET)
public ModelAndView showUserAdd(ServletRequest request, @ModelAttribute("userModel") UserModel userModel, ModelMap modelmap) {
ModelMap modelMap = new ModelMap();
userModel.setUser(new User());
userModel.setRoles(userService.getRoles());
modelMap.addAttribute("userModel", userModel);
return new ModelAndView("user/add", modelMap);
}
/**
* handle post request to handle user creation, if successful displays user list page
*
* @param user User object from JSP
* @param result BindingResult from JSP
* @return returns view name
*/
@RequestMapping(value="/user/add", method=RequestMethod.POST)
public String userAdd(UserModel userModel, BindingResult result) {
if (result.hasErrors()) {
logger.warn("Error binding UserModel for /user/add, returning to previous page");
List<ObjectError> errors = result.getAllErrors();
for (ObjectError error : errors) {
logger.warn(error.getCode() + " - " + error.getDefaultMessage());
}
return "user/add";
}
try {
User user = userModel.getUser();
userService.addUser(user);
}
catch (DuplicateKeyException e) {
logger.warn("Duplicate record found in User table", e);
}
catch (Exception e) {
logger.error("Error occurred while trying to create a new user", e);
}
return "/user";
}
这是我传递给JSP的模型,它包含一个User对象,它是Hibernate Entity,还有一个Roles列表,另一个是hibernate Entity。
import java.util.List;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.everesttech.recruiting.searchtool.entity.Role;
import com.everesttech.recruiting.searchtool.entity.User;
@Scope(value="request")
@Component("userModel")
public class UserModel {
public User user;
public List<Role> roles;
public UserModel() {
}
public UserModel(User user, List<Role> roles) {
this.user = user;
this.roles = roles;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
@Override
public String toString() {
return "UserModel [user=" + user + ", roles=" + roles + "]";
}
}
这是我的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 col-sm-8 col-md-6">
<h3>User - Add</h3>
<br>
<spring:hasBindErrors name="userModel">
<div class="alert alert-danger">
<sf:errors path="userModel.user.firstName"></sf:errors>
<sf:errors path="userModel.user.lastName"></sf:errors>
<sf:errors path="userModel.user.email"></sf:errors>
<sf:errors path="userModel.user.userName"></sf:errors>
<sf:errors path="userModel.user.password"></sf:errors>
<sf:errors path="userModel.user.role"></sf:errors>
</div>
</spring:hasBindErrors>
<c:url var="formAction" value="/user/add" />
<sf:form commandName="userModel" modelAttribute="userModel" method="post" action="${formAction}">
<div class="form-group">
<label for="first-name">First Name</label>
<sf:input path="user.firstName" id="first-name" class="form-control" placeholder="First Name" />
</div>
<div class="form-group">
<label for="last-name">Last Name</label>
<sf:input path="user.lastName" id="last-name" class="form-control" placeholder="Last Name" />
</div>
<div class="form-group">
<label for="email">Email</label>
<sf:input path="user.email" id="email" class="form-control" placeholder="Email" />
</div>
<div class="form-group">
<label for="user-name">Username</label>
<sf:input path="user.userName" id="user-name" class="form-control" placeholder="Username" />
</div>
<div class="form-group">
<label for="password">Password</label>
<sf:password path="user.password" id="password" class="form-control" placeholder="" />
</div>
<div class="form-group">
<label for="confirm-password">Confirm Password</label>
<input type="password" id="confirm-password" class="form-control" placeholder="" />
</div>
<div class="form-group">
<label for="role">Role</label>
<sf:select path="user.role" id="role" class="form-control" >
<c:forEach var="r" items="${userModel.roles}">
<sf:option value="${r.getId()}">${r.getFriendlyName()}</sf:option>
</c:forEach>
</sf:select>
</div>
<button type="submit" class="btn btn-default">Save</button>
<button type="button" class="btn btn-default">Cancel</button>
</sf:form>
</div>
</div>
</div>
答案 0 :(得分:1)
对于任何有兴趣的人,我在Spring文档中找到了一个解决方案。我必须创建一个类来处理从String到Role的转换并注册它。这必须访问数据库以创建Role对象,但我没有看到另一种处理它的方法。
这是我的班级。
import javax.inject.Inject;
import org.springframework.core.convert.converter.Converter;
import com.everesttech.recruiting.searchtool.dao.RoleDao;
import com.everesttech.recruiting.searchtool.entity.Role;
final class StringToRole implements Converter<String, Role> {
@Inject
RoleDao roleDao;
@Override
public Role convert(String source) {
return roleDao.find(Long.parseLong(source));
}
}
我在mvc-context.xml文件中添加/编辑了以下内容。
<!-- Enables the Spring MVC @Controller programming model -->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.examplecompany.exampleapp.example.converter.StringToRole"/>
</list>
</property>
</bean>
这有效,我现在能够提交表格而没有任何问题。但是现在,当User对象不满足验证要求时,我的hibernate验证没有出现在JSP上。例如,First Name有一个@NotBlank注释。我可以看到它被检测到并且我正在记录它。但是它们没有以形式出现在jsp上:错误标记。如果有人知道如何解决这个问题,请告诉我。