Spring MVC驗證器Validator

	<!-- JSR303 Validator定義 -->
	<bean id="validator"
		class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
</beans>

如果想要開啓Spring Framework的檢驗功能,需要定義一個驗證器Bean —>LocalValidatorFactoryBean
@Bean
public Validator getValidator()
{
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(this.messageSource());//支持國際化的錯誤信息
validator.setProviderClass(HibernateValidator.class);//指定驗證器實現的提供方
return validator;
}

JSR和Hibernate validator的校驗只能對Object的屬性(也就是Bean的域)進行校驗,不能對單個的參數進行校驗。
spring 在此基礎上進行了擴展,添加了MethodValidationPostProcessor攔截器,可以實現對方法參數的校驗
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor()
{
MethodValidationPostProcessor processor =
new MethodValidationPostProcessor();
processor.setValidator(this.localValidatorFactoryBean());
return processor;
}

在Springboot中會自動導入這兩個Bean,除非需要對Bean做定製,否則不需要顯示的定義這兩個Bean。
驗證POJO
被驗證的實體類
public class Foo {

@NotBlank
private String name;

@Min(18)
private Integer age;

@Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "手機號碼格式錯誤")
@NotBlank(message = "手機號碼不能爲空")
private String phone;

@Email(message = "郵箱格式錯誤")
private String email;

//... getter setter

}

驗證數據
public void myMethod1(@Validated Foo foo,BindingResult bingingResult)
{
if(bingingResult.hasErrors)
{
for(FieldError fieldError : bingingResult.getFieldErrors)
{

}
}
}

被@Validated註解的對象爲待驗證的對象,BindingResult爲驗證後存放的信息。每個Validated對應一個bindingResult
BingdingResult會被spring的驗證器自動填充,如果有錯誤,bingingResult.hasErrors的返回值會是true
基於方法進行校驗
在類前加上@Validated,在方法前加上需要驗證的註解–>對函數返回值進行校驗,在方法的傳入參數上加上需要驗證的註解—>對函數傳參進行校驗。
可以在傳入參數中加入BindingResult,捕獲校驗的結果。
也可以定義異常處理方法,捕獲驗證未通過拋出的異常
@RestController
@Validated
public class BarController {

@RequestMapping("/bar")
public @NotBlank String bar(@Min(18) Integer age) {
    System.out.println("age : " + age);
    return "";
}

@ExceptionHandler(ConstraintViolationException.class)
public Map handleConstraintViolationException(ConstraintViolationException cve){
    Set<ConstraintViolation<?>> cves = cve.getConstraintViolations();
    for (ConstraintViolation<?> constraintViolation : cves) {
        System.out.println(constraintViolation.getMessage());
    }
    Map map = new HashMap();
    map.put("errorCode",500);
    return map;
}

}

編寫自己的校驗類型
編寫自定義的校驗註解
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE,
ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {xxx.class})
@Pattern(regexp = “^[a-z0-9!#$%^&*'{}?/+=|_~-]+(\\.[a-z0-9!#&quot; ]+)@([az09]([az09][az09])?)+(.[az09]&quot;+&quot;([az09][az09])?)%^&amp;*&#x27;{}?/+=|&quot; + &quot;_~-]+)*@([a-z0-9]([a-z0-9-]*[a-z0-9])?)+(\\.[a-z0-9]&quot; + &quot;([a-z0-9-]*[a-z0-9])?)*”, flags = {Pattern.Flag.CASE_INSENSITIVE})
@ReportAsSingleViolation
public @interface Email
{
String message() default “”;

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

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

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE,
        ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
static @interface List {
    Email[] value();
}

}

@Constraint註解是定義校驗註解必備的註解,其中屬性validatedBy中可以填寫指定的檢驗器類型,@Pattern是繼承的其他註解,@ReportAsSingleViolation表示這個註解會和@pattern註解組合在一起,只引發一次錯誤。
有時候,需要自定義校驗器校驗指定類型的註解,則需要編寫自己的校驗器。編寫自己的校驗器需要實現標準的校驗器接口ConstraintValidator。第一個泛型是校驗註解,第二個泛型是需要校驗的類型。
public class xxx.class implements ConstraintValidator<Email,CharSequence>
{
public void initialize(NotBlank annotation){…}
public boolean isValid(CharSequence value, ConstraintValidatorContext context){…}
}

附:
@Null:限制只能爲null
@NotNull:限制必須不能爲空
@AssertFalse 限制必須爲false
@AssertTrue 限制必須爲true
@DecimalMax(value) 限制必須爲一個不大於指定值得數字
@DecimalMax(value)限制必須爲一個不小於指定值得數字
@Digits(integer,fraction)限制必須爲一個小數,且整數部分的位數不能超過integer,小數部分不能超過fraction
@Futrue 限制必須爲一個將來的日期
@Max(value) 限制必須爲一個不大於指定值得數字
@Min(value)限制必須爲一個不小於指定值得數字
@Past限制必須爲一個過去的時間
@Pattern(value)限制爲符合指定的正則表達式
@Size(max,min)限制字符長度在min 到 max 之間

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章