私は、Spring MVCバリデータに基づいて検証を行う必要がある、Spring MVCアプリケーションに取り組んでいます。そのための最初のステップとして、クラスとセットアップコントローラーに注釈を追加しましたが、正常に機能します。そして今、複雑なロジックを実行するためにカスタムバリデータを実装する必要がありますが、既存のアノテーションを使用して、追加のチェックを追加したいだけです。
My Userクラス:
public class User
{
@NotEmpty
private String name;
@NotEmpty
private String login; // should be unique
}
私のバリデーター:
@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");
}
}
}
私のコントローラー:
@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
}
}
}
だから、カスタムバリデータと注釈を一緒に使用することは可能ですか?そして、もしそうならどうですか?
これは一種の古い質問ですが、グーグルにとっては...
addValidators
の代わりにsetValidator
を使用する必要があります。次のように:
@InitBinder
protected void initBinder(final WebDataBinder binder) {
binder.addValidators(yourCustomValidator, anotherValidatorOfYours);
}
PS:addValidators
は複数のパラメーターを受け入れます(省略記号)
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));
}
....
}
ご覧のとおり、setValidator
は既存の(デフォルトの)バリデータをクリアするため、@Valid
アノテーションは期待どおりに機能しません。
問題を正しく理解している場合、カスタムバリデータを使用するとすぐに、@NotEmpty
注釈は発生しなくなりました。これは、springを使用する場合に一般的です。デフォルトで指定された機能をオーバーライドする場合、明示的に呼び出す必要があります。
LocalValidatorFactoryBean
を生成し、メッセージソース(存在する場合)を挿入する必要があります。次に、その基本的なバリデータをカスタムバリデータに挿入し、注釈の検証をそれに委任します。
Java設定を使用すると、次のようになります。
@Configuration
public class ValidatorConfig {
@Autowired
private MessageSource messageSource;
@Bean
public Validator basicValidator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(messageSource);
return validator;
}
}
次に、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");
}
}
}
まあ私にとっては、削除する必要があります
@InitBinder
protected void initBinder(final WebDataBinder binder)
{
binder.setValidator(validator);
}
出て
@Valid @ModelAttribute("user") final User user,
BindingResult result
そして関数makeの後
validator.validate(user,result)
このように、@ Validで基本的な検証を使用し、配置した後、より複雑な検証を行います。
InitBinderを使用すると、複雑なロジックを使用して検証を設定し、基本的なロジックを設定できるためです。
多分間違っている、私は常にバリデータなしで@Validを使用しています。