Ошибки JSR-303 не обнаружены изначально с помощью аннотации @Valid
Как получилось, что @Valid аннотация не улавливает мои аннотации JSR-303 изначально, но улавливает их с помощью следующего метода:
WebConfig.java
@Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
String[] strBaseNames = {
"resources.messages.layout.LayoutResources",
"resources.messages.layout.MenuResources",
"resources.messages.global.GlobalResources"
};
messageSource.setUseCodeAsDefaultMessage(true);
messageSource.setDefaultEncoding("UTF-8");
messageSource.setBasenames(strBaseNames);
return messageSource;
}
@Bean
public LocalValidatorFactoryBean jsr303Validator() {
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
localValidatorFactoryBean.setValidationMessageSource(this.messageSource());
return localValidatorFactoryBean;
}
UserController.java
@Controller
@RequestMapping(value = "/security/user", method = RequestMethod.GET)
public class UserController {
@Autowired
private SecurityService securityService;
@Autowired
SessionObject sessionObject;
@Autowired
@Qualifier("jsr303Validator") Validator validator;
@RequestMapping(value = "/edit/validate", method = RequestMethod.POST)
public String validateEdit( @ModelAttribute @Valid User user,
BindingResult result,
Model model) {
String strViewName = "common/error";
validator.validate(user, result);
if(result.hasErrors()) {
strViewName = "user/userEdit";
} else {
... update work ...
strViewName = "user/success";
}
return strViewName;
}
Если я использую только аннотацию @Valid, результат.hasErrors () всегда пуста, поэтому в итоге у меня возникает исключение ConstraintViolationException ниже), что вполне ожидаемо. Но я хотел бы, чтобы он работал, используя только аннотацию @Valid, без необходимости автоматического подключения моего jsr303validator bean в каждом контроллере, который я хочу реализовать некоторые проверки JSR-303.
Трассировка журнала нарушений ограничений
Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [spring4base.model.security.User] during update time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='error.firstname.notnull', propertyPath=strFirstName, rootBeanClass=class spring4base.model.security.User, messageTemplate='error.firstname.notnull'}
ConstraintViolationImpl{interpolatedMessage='error.userid.notnull', propertyPath=strUserId, rootBeanClass=class spring4base.model.security.User, messageTemplate='error.userid.notnull'}
ConstraintViolationImpl{interpolatedMessage='error.lastname.notnull', propertyPath=strLastName, rootBeanClass=class spring4base.model.security.User, messageTemplate='error.lastname.notnull'}
]
Пользователь.java
@NotBlank(message = "error.userid.notnull")
@Size(min = 0, max = 14, message = "error.firstname.length")
private String strUserId = "";
@NotBlank(message = "error.firstname.notnull")
@Size(min = 0, max = 50, message = "error.firstname.length")
private String strFirstName = "";
@NotBlank(message = "error.lastname.notnull")
@Size(min = 0, max = 50, message = "error.lastname.length")
private String strLastName = "";
Спасибо
1 ответ:
Для того, чтобы это сработало в моем случае, требовалось следующее:
Сначала определите LocalValidatorFactoryBean в моем классе Java Config (WebAppContext.java в моем случае).
@Bean public ResourceBundleMessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); String[] baseNames = { "resources.messages.layout.LayoutResources", "resources.messages.layout.MenuResources", "resources.messages.option.AppConfigResources", "resources.messages.global.GlobalResources", "resources.messages.contact.ContactResources", "resources.messages.currentsession.CurrentSessionResources", "resources.messages.welcome.WelcomeResources", "resources.messages.user.UserResources", "resources.messages.role.RoleResources", "resources.messages.profile.ProfileResources" }; messageSource.setCacheSeconds(60); messageSource.setFallbackToSystemLocale(false); messageSource.setUseCodeAsDefaultMessage(true); messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name()); messageSource.setBasenames(baseNames); return messageSource; } @Bean public LocalValidatorFactoryBean jsr303Validator() { LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean(); localValidatorFactoryBean.setValidationMessageSource(this.messageSource()); return localValidatorFactoryBean; }
Затем в моем контроллере я автоматически подключаю этот валидатор следующим образом:
@Autowired private Validator jsr303Validator;
И затем, единственный способ, который я нашел, чтобы выполнить мой JSR-303, это запустить их вручную, вот так:
@RequestMapping(value = "/update", method = RequestMethod.POST) public String processUpdate(@ModelAttribute UserForm userForm, BindingResult result, RedirectAttributes redirectAttributes, SessionStatus status) throws CheckedPersistenceException { this.userFormValidator.validate(userForm, result); if (!result.hasErrors()) { this.jsr303Validator.validate(userForm, result); } if(result.hasErrors()) { return this.UPDATE_VIEW; } ... }