java - valid - spring mvc formulario ejemplo
Primavera: el validador personalizado no se está llamando (4)
Estaba viendo otras preguntas sobre los validadores personalizados de Spring, pero desafortunadamente no pude resolver mi problema con las respuestas propuestas.
Mi problema es el siguiente: Tengo una entidad (Cuenta) y he creado un validador personalizado (AccountValidator) que utilizo en un controlador (RegisterController), pero nunca se invoca usando el Validator predeterminado.
¿Estoy olvidando algo? Adjunto parte del código para ayudar a comprender mejor mi problema.
Validador:
public class AccountValidator implements Validator{
@Override
public boolean supports(Class<?> clazz) {
return (Account.class).isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
//Validation code
}
}
Controlador:
@Controller
@RequestMapping(value = "/register")
public class RegisterController {
@Autowired
private AccountValidator accountValidator;
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields("id");
binder.setValidator(accountValidator);
}
@RequestMapping(method = RequestMethod.GET)
@ModelAttribute
public Account register(Locale currentLocale){
Account account = new Account();
return account;
}
@RequestMapping(method = RequestMethod.POST)
public String handleRegister(@Valid @ModelAttribute Account account, BindingResult result){
if(result.hasErrors()){
return "/register";
}
return "home";
}
}
Revisé mis mensajes de depuración en el registro y se está llamando al método initBinder, pero el método de validación nunca se está ejecutando.
¿Alguien puede ayudarme?
Tuve el mismo problema y resultó que recibía una excepción de SQL, aparentemente omitiendo mi validador porque tenía mi método anotado con @Transactional.
Después de WebDataBinder
el código fuente, el único motivo que puedo encontrar para que WebDataBinder
no invoque a su Validator
es que su variable es null
. Este campo
@Autowired
private AccountValidator accountValidator;
debe ser null
. No sé cómo llegaste allí, Spring se quejaría si no pudiera autoconectar un campo.
Por el momento, no puedo decirle por qué no se llama al Validator
cuando se registra con WebDataBinder
, pero esta es la solución:
Deshacerse de
binder.setValidator(accountValidator);
y agregue la llamada Validator
en el método del controlador
@RequestMapping(method = RequestMethod.POST)
public String handleRegister(@Valid @ModelAttribute Account account, BindingResult result){
accountValidator.validate(account, result);
if(result.hasErrors()){
return "/register";
}
return "home";
}
Spring realizará la validación por defecto (en función de su proveedor de validación, por ejemplo Hibernate) y luego aplicará su validación personalizada.
Creo que quieres usar binder.addValidator(accountValidator);
en lugar de binder.setValidator(accountValidator);
Estaba enfrentando el mismo problema y lo solucioné declarando la clase AccountValidator en el archivo xml de contexto y usando @validated
en lugar de @valid
.