2012-01-11 12 views
5

Dado que springmvc 3.x ahora es compatible con jsr303 y con el viejo validador de estilo de muelles, quiero mezclarlos en mis aplicaciones de muestra. Pero solo hay un método habilitado para un controlador específico, ¿es ese el límite del marco de primavera o el estándar JSR?El validador springmvc jsr303 coexiste con el validador WebDataBinder de resorte en una acción

Aquí está mi código de muestra.

User.java, representa el modelo de dominio, utiliza JSR303 para validación.

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

UserValidator.java, implementa la interfaz org.springframework.validation.Validator para apoyar la validación del usuario.

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, utiliza InitBinder anotación para inyectar UserValidator en WebDataBinder.

@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"; 
    } 
} 

Si elimine el comentario @InitBinder("user") en UserController, la validación JSR303 se desactivará. Mientras que el código comentado actual usará el validador JSR para hacer la validación. ¿Alguien puede darme una solución para mezclarlos en un solo controlador?

+1

Por cierto, puede deshacerse del tamaño codificado en el mensaje para la restricción '@ Size' utilizando marcadores de posición, como esto:' "user loginId max-length es {max}" ' –

Respuesta

6

Puede utilizar el validador directamente y dejar que el LocalValidatorFactoryBean mundial (JSR-303) haga su trabajo así:

@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

Genial, creo que es el elegante solución en comparación con mi actual. No 'InitBinder' para un atributo de modelo particular. Gracias – Bigfei

+0

Esto me ayudó, muy apreciado – jarandaf

8

Usted puede añadir su validador En lugar de dejarlo:

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

Esto ejecutará las validaciones JSR303 primero y luego su validador personalizado. No es necesario llamar al validador directamente en el método de guardar.

Cuestiones relacionadas