簡體   English   中英

@Valid帶有彈簧注釋

[英]@Valid with spring annotations

我已經為我的項目啟用了spring mvc注釋驅動。 這個想法是將@Valid注釋與spring注釋一起使用,以避免在控制器中出現以下行: validator.validate(form, errors)

我注意到,這些東西不適用於包中的spring注釋:

org.springmodules.validation.bean.conf.loader.annotation.handle

經過調查,我發現我可以使用javaxorg.hibernate.validator.constraints注釋作為替代方法。

但是不幸的是,在某些特殊情況下,我無法實現此目標:

@MinSize(applyIf = "name NOT EQUALS 'default'", value = 1)

最好知道spring注釋可以與@Valid或其他任何替代方式一起使用,以避免與applyIf屬性相關的重構(將條件移至Java代碼)。

這是如何創建自定義驗證程序的示例。

首先,創建您自己的注釋:

@Target({ ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = StringValidator.class)
public @interface ValidString {

    String message() default "Invalid data";
    int min() default -1;
    int max() default -1;
    String regex() default "";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

然后,您將需要一個自定義驗證器:

public class StringValidator implements ConstraintValidator<ValidString, String> {

    private int              _min;
    private int              _max;
    private String           _regex;
    private boolean          _decode;

    public void initialize(ValidString constraintAnnotation) {
        _min = constraintAnnotation.min();
        _max = constraintAnnotation.max();
        _regex = constraintAnnotation.regex();
        _decode = constraintAnnotation.decode();
    }

    public boolean isValid(String value, ConstraintValidatorContext context) {

        if (value == null) {
            return false;
        }

        String test = value.trim();

        if (_min >= 0) {
            if (test.length() < _min) {
                return false;
            }
        }

        if (_max > 0) {
            if (test.length() > _max) {
                return false;
            }
        }

        if (_regex != null && !_regex.isEmpty()) {
            if (!test.matches(_regex)) {
                return false;
            }
        }

        return true;
    }
}

最后,您可以在Bean和Controller中使用它:

public class UserForm {

    @ValidString(min=4, max=20, regex="^[a-z0-9]+")
    private String name;

    //...
}

// Method from Controller
@RequestMapping(method = RequestMethod.POST)
public String saveUser(@Valid UserForm form, BindingResult brResult) {

    if (brResult.hasErrors()) {
        //TODO:
    }

    return "somepage";
}

這樣的事情可能會幫助你

public class UserValidator implements Validator {

    @Override
    public boolean supports(Class clazz) {
      return User.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
      User user = (User) target;

      if(user.getName() == null) {
          errors.rejectValue("name", "your_error_code");
      }

      // do "complex" validation here

    }

}

然后在您的控制器中,您將:

@RequestMapping(value="/user", method=RequestMethod.POST)
    public createUser(Model model, @ModelAttribute("user") User user, BindingResult result){
        UserValidator userValidator = new UserValidator();
        userValidator.validate(user, result);

        if (result.hasErrors()){
          // do something
        }
        else {
          // do something else
        }
}

如果存在驗證錯誤,則result.hasErrors()將為true。

注意:您也可以使用“ binder.setValidator(...)”在控制器的@InitBinder方法中設置驗證器。 或者,您可以在控制器的默認構造函數中實例化它。 或者在控制器中插入一個@Component/@Service UserValidato r( @Autowired ):非常有用,因為大多數驗證器都是單例+單元測試模擬變得更容易+驗證器可以調用其他Spring組件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM