无法将Object类型的值转换为所需类型的Object Spring

时间:2017-03-13 16:26:15

标签: spring spring-mvc

我有两个数据Model User和Car:

User.java:

@Entity
@Table(name="APP_USER")
public class User implements Serializable{

@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
......

@OneToMany(mappedBy="user",cascade=CascadeType.ALL)
private Set<Car> cars = new HashSet<Car>();

Car.java:

@Entity
public class Car implements Serializable {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id ;
.....

@ManyToOne(optional=false)
@JoinColumn(name="user_fk")
private User user;

在Controller中,我想添加一个新用户,所以

AppController.java:

@Controller
@RequestMapping("/")
@SessionAttributes("roles")
public class AppController {

@RequestMapping(value = { "/newuser" }, method = RequestMethod.GET)
public String newUser(ModelMap model) {
    User user = new User();
    model.addAttribute("user", user);
    model.addAttribute("edit", false);
    model.addAttribute("loggedinuser", getPrincipal());
    return "registration";
}

@RequestMapping(value = { "/newuser" }, method = RequestMethod.POST)
public String saveUser(@ModelAttribute @Valid User user, BindingResult result,
        ModelMap model) {

    if (result.hasErrors()) {
        return "registration";
    }

    if(!userService.isUserSSOUnique(user.getId(), user.getSsoId())){
        FieldError ssoError =new FieldError("user","ssoId",messageSource.getMessage("non.unique.ssoId", new String[]{user.getSsoId()}, Locale.getDefault()));
        result.addError(ssoError);
        return "registration";
    }

    userService.saveUser(user);
    model.addAttribute("success", "User " + user.getFirstName() + " "+ user.getLastName() + " registered successfully");
    model.addAttribute("loggedinuser", getPrincipal());
    return "registrationsuccess";
}

另外,我创建了一个名为StringToUser的类(Implements Converter,所以我可以添加一个包含用户的新Car)

StringtoUser.java:

@Autowired
UserService userService ;

@Override
public User convert(Object element) {
    Integer id = Integer.parseInt((String)element);
    User user = userService.findById(id);
    return user;
}

AppController.java和saveUser方法在我添加StringToUser类之前工作正常。但是在我创建了StringToUser类之后,我在saveUser方法中出错了

The error is : WARNING: Failed to bind request element: org.springframework.beans.TypeMismatchException: Failed to convert value of type [com.websystique.springmvc.model.User] to required type [com.websystique.springmvc.model.User]; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [com.websystique.springmvc.model.User] to type [@org.springframework.web.bind.annotation.ModelAttribute @javax.validation.Valid com.websystique.springmvc.model.User] for value 'User [id=null, ssoId=alaa, password=alaa1991, firstName=, lastName=, email=, userProfiles=null, accounts=null, userDocuments=[], cars=[], documents=[]]'; nested exception is java.lang.ClassCastException: com.websystique.springmvc.model.User cannot be cast to java.lang.String

编辑:

错误:

WARNING: Failed to bind request element: org.springframework.beans.TypeMismatchException: Failed to convert value of type [com.websystique.springmvc.model.User] to required type [com.websystique.springmvc.model.User]; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [com.websystique.springmvc.model.User] to type [@org.springframework.web.bind.annotation.ModelAttribute @javax.validation.Valid com.websystique.springmvc.model.User] for value 'User [id=null, ssoId=alaa, password=alaa1991, firstName=, lastName=, email=, userProfiles=null, accounts=null, userDocuments=[], cars=[], documents=[]]'; nested exception is java.lang.NullPointerException

1 个答案:

答案 0 :(得分:0)

您不需要使用转换器,spring本身会将您的表单格式化为 User 类。

如果调试转换器类,您会注意到没有收到String作为参数,您会收到对类 User 的实例的引用。因此,您将用户转换为无意义的用户。

@Override
    public User convert(Object element) {
        if (element == null ) {
            return null;
        }
        Integer id = ((User)element).getId();
        User user = userService.findById(id);
        return user;
    }

现在,由于您尝试创建新用户,因此您的表单未设置和ID,因此您提供 userService null。您的服务失败,转换器无法显示该错误。

简单的解决方案就是删除它。

我理解你添加了角色转换器,因为表单正在向你发送一个整数列表,这些整数无法通过spring解析为Set。我强烈建议您将Command Objects实现为模型的中介,这样就可以避免使用Set。

但如果您需要实施转换器,我建议在下面进行更改:

@Component
public class RoleToUserProfileConverter implements Converter<Object, UserProfile>{

    static final Logger logger = LoggerFactory.getLogger(RoleToUserProfileConverter.class);

    @Autowired
    private UserProfileService userProfileService;


    private HashMap<Integer, UserProfile> userProfiles;

    /**
     * Gets UserProfile by Id
     * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
     */
    public UserProfile convert(Object element) {
        Integer id = Integer.parseInt((String)element);
        UserProfile profile = findUserProfile(id);
        logger.info("Profile : {}",profile);
        return profile;
    }

    private UserProfile findUserProfile(Integer id) {
        //First time loading profiles
        if(userProfiles == null) {
            userProfiles = new HashMap<>();
            List<UserProfile> userProfileList = userProfileService.findAll();
            for(UserProfile userProfile: userProfileList) {
                userProfiles.put(userProfile.getId(), userProfile);
            }
        }
        if(userProfiles.containsKey(id)) {
            return userProfiles.get(id);
        }
        return null;
    }

}

在这个例子中,我使用一个hashmap来保存所有应该更少的UserProfile,然后第一次加载并重新加载。

您可以通过检查您正在查找的ID是否在哈希中来改进它,以便查询数据库并存储它,这样就可以按需加载新的UserProfiles。