Java Spring MVC 验证器注解+自定义验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25075683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring MVC validator annotation + custom validation
提问by Vartlok
I'm working on spring mvc application, where I should aplly validation based on Spring MVC validator. I first step for that I added annotation for class and setup controller and it works fine. And now I need to implement custom validator for perform complex logic, but i want to use existing annotation and just add additional checking.
我正在研究 spring mvc 应用程序,我应该在其中应用基于 Spring MVC 验证器的验证。我的第一步是为类和设置控制器添加了注释,它工作正常。现在我需要实现自定义验证器来执行复杂的逻辑,但我想使用现有的注释并添加额外的检查。
My User class:
我的用户类:
public class User
{
@NotEmpty
private String name;
@NotEmpty
private String login; // should be unique
}
My validator:
我的验证器:
@Component
public class UserValidator implements Validator
{
@Autowired
private UserDAO userDAO;
@Override
public boolean supports(Class<?> clazz)
{
return User.class.equals(clazz) || UsersForm.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors)
{
/*
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "NotEmpty.user");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "login", "NotEmpty.user");
*/
User user = (User) target;
if (userDAO.getUserByLogin(user.getLogin()) != null) {
errors.rejectValue("login", "NonUniq.user");
}
}
}
My controller:
我的控制器:
@Controller
public class UserController
{
@Autowired
private UserValidator validator;
@InitBinder
protected void initBinder(final WebDataBinder binder)
{
binder.setValidator(validator);
}
@RequestMapping(value = "/save")
public ModelAndView save(@Valid @ModelAttribute("user") final User user,
BindingResult result) throws Exception
{
if (result.hasErrors())
{
// handle error
} else
{
//save user
}
}
}
So, Is it possible to use custom validator and annotation together? And if yes how?
那么,是否可以同时使用自定义验证器和注释?如果是,如何?
采纳答案by destan
I know this is a kind of old question but, for googlers...
我知道这是一个老问题,但是,对于谷歌员工......
you should use addValidators
instead of setValidator
. Like following:
你应该使用addValidators
而不是setValidator
. 像下面这样:
@InitBinder
protected void initBinder(final WebDataBinder binder) {
binder.addValidators(yourCustomValidator, anotherValidatorOfYours);
}
PS: addValidators
accepts multiple parameters (ellipsis)
PS:addValidators
接受多个参数(省略号)
if you checkout the source of org.springframework.validation.DataBinder
you will see:
如果你签出你的来源,org.springframework.validation.DataBinder
你会看到:
public class DataBinder implements PropertyEditorRegistry, TypeConverter {
....
public void setValidator(Validator validator) {
assertValidators(validator);
this.validators.clear();
this.validators.add(validator);
}
public void addValidators(Validator... validators) {
assertValidators(validators);
this.validators.addAll(Arrays.asList(validators));
}
....
}
as you see setValidator
clears existing (default) validator so @Valid
annotation won't work as expected.
如您所见,setValidator
清除现有(默认)验证器,因此@Valid
注释将无法按预期工作。
回答by nicearma
Well for me you have to delete the
对我来说,你必须删除
@InitBinder
protected void initBinder(final WebDataBinder binder)
{
binder.setValidator(validator);
}
Leave the
离开
@Valid @ModelAttribute("user") final User user,
BindingResult result
And after in the function make
在函数 make 之后
validator.validate(user,result)
This way you will use the validation basic with the @Valid and after you will put make the more complex validation.
通过这种方式,您将使用带有 @Valid 的验证基础,然后进行更复杂的验证。
Because with the initBinder you are setting the validation with your complex logic and putting a way the basic logic.
因为使用 initBinder,您可以使用复杂的逻辑设置验证并设置基本逻辑。
Maybe is wrong, i use always the @Valid without any validator.
也许是错误的,我总是使用没有任何验证器的@Valid。
回答by Serge Ballesta
If I correctly understand your problem, as soon as you use you custom validator, default validation for @NotEmpty
annotation no longer occurs. That is common when using spring : if you override a functionnality given by default, you have to call it explicitely.
如果我正确理解您的问题,一旦您使用自定义验证器,@NotEmpty
注释的默认验证将不再发生。这在使用 spring 时很常见:如果您覆盖默认提供的功能,则必须明确调用它。
You have to generate a LocalValidatorFactoryBean
and inject it with your message source (if any). Then you inject that basic validator in you custom validator and delegate annotation validation to it.
您必须生成 aLocalValidatorFactoryBean
并将其注入您的消息源(如果有)。然后,您在自定义验证器中注入该基本验证器,并将注释验证委托给它。
Using java configuration it could look like :
使用 java 配置它可能看起来像:
@Configuration
public class ValidatorConfig {
@Autowired
private MessageSource messageSource;
@Bean
public Validator basicValidator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(messageSource);
return validator;
}
}
Then you modify UserValidator
to use it :
然后你修改UserValidator
使用它:
@Component
public class UserValidator implements Validator
{
@Autowired
@Qualifier("basicValidator")
private Validator basicValidator;
@Autowired
private UserDAO userDAO;
// ...
@Override
public void validate(Object target, Errors errors)
{
basicValidator.validate(target, errors);
// eventually stop if any errors
// if (errors.hasErrors()) { return; }
User user = (User) target;
if (userDAO.getUserByLogin(user.getLogin()) != null) {
errors.rejectValue("login", "NonUniq.user");
}
}
}