2012-01-11 67 views
5

由于springmvc 3.x现在支持jsr303和旧式弹簧样式验证器,我想将它们混合到我的示例应用程序中。但是对于指定的控制器只有一种方法可用,是Spring框架还是JSR标准的限制?springmvc jsr303验证器在一个动作中与Spring WebDataBinder验证器共存

这是我的示例代码。

User.java代表领域模型,使用JSR303进行验证。

public class User{ 
    @Size(max = 16, message = "user loginId max-length is 16") 
    private String loginId; 
    //omit getter and setter 
} 

UserValidator.java,实现了org.springframework.validation.Validator接口,以支持用户验证。

public class UserValidator implements Validator { 

    private UserService userService; 
    public boolean supports(Class<?> clazz) { 
     return User.class.isAssignableFrom(clazz); 
    } 

    public void validate(Object target, Errors errors) { 
      User u = (User) target; 

      // loginName check for new user 
      if (u.getUserId() == null && !userService.isLoginIdUnique(u.getLoginId(), null)) { 
        errors.rejectValue("loginId", "user.loginId.unique", new Object[] { u.getLoginId() }, null); 
      } 
    } 

    @Autowired 
    public void setUserService(UserService userService) { 
      this.userService = userService; 
    } 

} 

UserController.java,使用InitBinder注释注入UserValidatorWebDataBinder

@Controller("jspUserController") 
@RequestMapping("/sys/users") 
public class UserController { 
    private UserValidator userValidator; 

    @Autowired 
    public void setUserValidator(UserValidator userValidator) { 
     this.userValidator = userValidator; 
    } 

/*@InitBinder("user") 
    public void initBinderUser(WebDataBinder binder) { 
     binder.setValidator(userValidator); 
    }*/ 

    @RequestMapping(value = "/save") 
    public String save(@Valid User user, BindingResult bindingResult, Model model, HttpServletRequest request) { 
     if (bindingResult.hasErrors()) { 
      return "/sys/user/edit"; 
     } 
     userService.saveUser(user); 
     return "redirect:/sys/users/index"; 
    } 
} 

如果我取消在UserController中的@InitBinder("user"),在JSR303验证将被禁用。虽然当前评论的代码将使用JSR验证器来进行验证。 任何人都可以给我一个解决方法,混合他们在一个控制器?

+1

顺便说一句,你可以通过使用占位符来消除'@ Size'约束的消息中的硬编码大小,如下所示:''user loginId max-length is {max}“' – 2012-01-14 08:13:21

回答

6

您可以直接使用您的验证,让全球LocalValidatorFactoryBean(JSR-303)做的工作还有:

@Controller("jspUserController") 
    @RequestMapping("/sys/users") 
    public class UserController { 
     private UserValidator userValidator; 

     @Autowired 
     public void setUserValidator(UserValidator userValidator) { 
      this.userValidator = userValidator; 
     } 

     @RequestMapping(value = "/save") 
     public String save(@Valid User user, BindingResult bindingResult, Model model, HttpServletRequest request) { 
      this.userValidator.validate(user, bindingResult); 
      if (bindingResult.hasErrors()) { 
       return "/sys/user/edit"; 
      } 
      userService.saveUser(user); 
      return "redirect:/sys/users/index"; 
     } 
    } 
+1

好极了,我认为它是优雅的与我目前的解决方案相比。对于特定的模型属性没有'InitBinder'。谢谢 – Bigfei 2012-01-12 03:47:02

+0

这帮了我很大的忙 – jarandaf 2013-07-08 12:47:14

8

您可以添加的,而不是将它设置你的验证:

@InitBinder("user") 
public void initBinderUser(WebDataBinder binder) { 
    binder.addValidators(userValidator); 
} 

这将首先执行JSR303验证,然后执行您的自定义验证器。不需要直接在保存方法中调用验证器。