2012-01-11 42 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驗證,然後執行您的自定義驗證器。不需要直接在保存方法中調用驗證器。