1. 매개 변수 검증
개발에서 비어 있지 않은 필드, 필드 길이 제한, 사서함 형식 확인 등과 같은 필드 검증을위한 코드를 작성해야합니다. 비즈니스 로직과 거의 관련이없는 이러한 코드를 작성할 때 두 가지 문제가 있다고 개인적으로 생각합니다.
Hibernate Validator (공식 문서)는 비교적 완전하고 편리한 검증 구현 방법을 제공합니다.
스프링 부트 스타터 -WEB 패키지에는 최대 절전 모드-발전기 패키지가 있으며 최대 절전 모드 유효성 검사기 종속성을 참조 할 필요가 없습니다.
2. 최대 절전 모드 유효성 검사 검증 데모
먼저 간단한 데모를 살펴보고 Validator의 주석을 추가하겠습니다.
import org.hibernate.validator.constraints.notblank; import javax.validation.constraints.assertfalse; import javax.validation.constraints.pattern;
@getter@setter@noargsconstructorpublic class demomodel {@notblank (message = "사용자 이름이 비어있을 수 없다") 개인 문자열 사용자 이름; @NotBlank (메시지 = "Age ="Age invime ") @pattern (regexp ="^[0-9] {1,2} $ ", Message ="Age Night ") 개인 문자열 연령; @assertfalse (메시지 = "거짓이어야한다") private boolean isfalse; / *** 비어 있으면 점검되지 않으며 비어 있지 않으면 비어 있지 않으면*/ @pattern (regexp = "^[0-9] {4}-[0-9] {0-9]-[0-9] {2} $", 메시지 = "출생 날짜가 틀 렸습니다") 개인 문자열 생일;}.Post Interface Verification, BindingResult는 확인을 전달하지 못하는 결과 모음입니다.
@requestmapping ( "/demo2") public void demo2 (@requestbody @valid demomodel demo, bindingResult result) {if (result.haserrors ()) {for (objecterror error : result.getallerrors ()) {system.out.println (error.getDefaultMessage ()); }}} 사후 요청에 의해 전달되는 매개 변수 :{"userName":"dd","age":120,"isFalse":true,"birthday":"21010-21-12"}
출력 결과 :
생년월일이 잘못되었고 거짓이어야합니다.
잘못된 나이
매개 변수 검증은 매우 편리합니다. 필드의 주석 + 검증이 전달되지 않으면 많은 비어 있지 않은 필드 제한 검증 코드의 필기를 대체 할 수 있습니다. 아래는 매개 변수 검증을 수행하는 방법에 대한 더 깊은 이해가 있습니다.
3. 최대 절전 모드 검증 모드
신중한 독자는 위의 예에서 확인을 전달하지 못하는 모든 세트가 한 번에 반환된다는 것을 발견했을 것입니다. 일반적으로 첫 번째 필드가 정리의 확인 요구 사항을 충족하지 않으면 요청을 직접 거부 할 수 있습니다. 최대 절전 모드 유효성 검사기에는 다음 두 가지 검증 모드가 있습니다.
1. 일반 모드 (이 모드는 기본값)
일반 모드 (모든 속성이 확인되고 모든 확인 실패 정보가 반환됩니다)
2. 빠른 모드로 돌아 오지 못한다
빠른 고장 반환 모드 (확인 실패가있는 한 반환)
두 가지 검증 모드 구성 방법 : (공식 문서 참조)
실패 : 진정한 빠른 실패 리턴 모드 False Normal Mode
validatorFactory validatorFactory = validation.ByProvider (hibernateValidator.class) .configure () .failfast (true) .buildValidatorFactory (); Validator Validator = validatorfactory.getValidator ();
and (hibernate.validator.fail_fast : 진정한 빠른 실패 리턴 모드 False Normal Mode)
validatorfactory validatorfactory = validation.byprovider (hibernatevalidator.class) .configure () .addproperty ( "hibernate.validator.fail_fast", "true") .BuildValidatorActory (); Validator Validator = validatorfactory.getValidator ();
4. 최대 절전 모드의 두 가지 유형의 검증
최대 절전 모드 유효성 검사기를 빠른 고장으로 반환 모드로 구성하십시오.
@ConfigurationPublic Class ValidatorConfiguration {@bean public validator validator () {validatorFactory validatorFactory = validation.ByProvider (hibernateValidator.class) .configure () .addproperty ( "hibernate.validator.fail_fast", "true"); Validator Validator = validatorfactory.getValidator (); 반환 유효성 검사기; }}1. 요청 매개 변수 확인
데모의 예에서와 같이, 요청 매개 변수를 확인할 때 @requestbody demomodel demo 사이에 @valid를 추가 한 다음 bindindresult를 추가하십시오. 여러 매개 변수의 경우 다음과 같은 여러 @valid 및 bindingResult를 추가 할 수 있습니다.
public void test () ( @requestbody @valid demomodel demo, bindingResult 결과) public void test () ( @requestbody @valid demomodel demo, bindingResult result, @requestody @valid demomodel demo2, bindingresult result2)
@requestmapping ( "/demo2") public void demo2 (@requestbody @valid demomodel demo, bindingResult result) {if (result.haserrors ()) {for (objecterror error : result.getallerrors ()) {system.out.println (error.getDefaultMessage ()); }}}2. 매개 변수 확인 (@requestparam 매개 변수 확인)
Bean을 점검하는 방법을 사용하여 RequestParam의 내용을 확인할 방법이 없습니다. 일반적으로 요청을받을 때 요청 (또는 더 적은 매개 변수)을 사용하면 다음 코드가 사용됩니다.
@requestmapping (value = "/demo3", method = requestmethod.get) public void demo3 (@requestparam (name = "grade", 필수 = true) int grade,@requestparam (name = "classroom", residt = true) {System.out.println (grad + "," + Crassroom); }@Valid 주석을 사용하여 RequestParam에 해당하는 매개 변수에 유효하지 않습니다. 검증을 발효하려면 @Validated 주석이 필요합니다. 아래 그림과 같이 :
에이. 현재 MethodValidationPostProcessor 의 Bean을 사용해야합니다.
@Bean public methodValidationPostSprocessor methodValidationPostProcessor () { / ** 기본값은 일반 모드이며 정보 수집을 전달하지 않고 모든 검증이 반환됩니다* / return new MethodValidationPostProcessor (); } 또는 MethodValidationPostProcessor 의 유효성 검사기를 설정할 수 있습니다 (현재 유효성 검사기가 검증에 사용되지 않기 때문에 유효성 검사기 구성이 작동하지 않음).
@Bean public methodValidationPostProcessor methodValidationPostProcessor () {MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor (); / ** 유효성 검사 모드를 빠른 고장으로 설정*/ postprocessor.setValidator (validator ()); 반환 후 프로세서; } @Bean public validator validator () {validatorFactory validatorFactory = validation.ByProvider (hibernateValidator.class) .configure () .addProperty ( "hibernate.validator.fail_fast", "true") .BuildValidatorFactory (); Validator Validator = validatorfactory.getValidator (); 반환 유효성 검사기; }비. 메소드가있는 컨트롤러에 주석을 추가 @Validated
@requestmapping ( " /validation")@restcontroller@validatepublic class validationcontroller { /** 객체 만있는 경우 컨트롤러 계층에 매개 변수를 쓰고 컨트롤러 계층에서 확인하십시오. */ @RequestMapping (value = "/ demo3", method = requestmethod.get) public void demo3 (@Range (min = 1, max = 9, max = 9, mains = "grade ="1-9 ") @RequestParam (name ="grade ", request = @min (value = 1, message ="can can 1 ") @max (value = 99, wesome). 99 ") @requestparam (이름 ="교실 ", 필수 = true) int classroom) {System.out.println (grade +", " + Classroom); }}기음. 확인 정보 프롬프트로 돌아갑니다
확인할 수 있습니다 : 확인이 실패하면 제약 범위 지출 예외가 발생하고 동일한 캐치 예외가 처리됩니다.
@controllerAdvice @componentPublic Class globalexceptionHandler {@exceptionHandler @ResponseBody @ResponSestatus (httpstatus.bad_request) public String handle (validationException Exception) {IF (예외 제한 력 예수 exception) {supstraintViolationException = 예외; set <ranstraintViolation <? >> 위반 = exs.getConstraintViolations (); for (제약 범위 <?> 항목 : 위반) { / ** verification* / system.out.println (item.getMessage ())를 전달하지 못하는 정보를 인쇄합니다. }} "나쁜 요청"을 반환합니다. }}디. 확인
브라우저 서비스 요청 주소 : http : // localhost : 8080/validation/demo3? grade = 18 & classroom = 888
빠른 고장을 구성하지 않고 MethodValidationPostProcessor가 반환 된 경우 출력 정보는 다음과 같습니다.
등급은 1-9 일만 할 수 있습니다
최대 클래스는 99 일만 할 수 있습니다
MethodValidationPostProcessor가 빠른 고장 리턴으로 구성되면 출력 정보는 다음과 같습니다.
등급은 1-9 일만 할 수 있습니다
브라우저 서비스 요청 주소 : http : // localhost : 8080/validation/demo3? grade = 0 & classroom = 0
빠른 고장을 구성하지 않고 MethodValidationPostProcessor가 반환 된 경우 출력 정보는 다음과 같습니다.
등급은 1-9 일만 할 수 있습니다
최소 클래스는 1 일 수 있습니다
MethodValidationPostProcessor가 빠른 고장 리턴으로 구성되면 출력 정보는 다음과 같습니다.
등급은 1-9 일만 할 수 있습니다
3. 모델 검증
확인할 모델 :
@datapublic class demo2 {@length (min = 5, max = 17, message = "길이 길이는 [5,17]") 개인 문자열 길이; / ** @size는 문자열, 수집, 맵 및 배열에 적합한 정수를 확인할 수 없습니다*/ @size (min = 1, max = 3, message = "size tire [1,3]") 개인 문자열 연령; @Range (Min = 150, max = 250, message = "범위는 [150,250]") 개인 int High; @Size (min = 3, max = 5, message = "목록의 크기는 [3,5]에 있습니다") 개인 목록 <string> 목록;}모델을 확인하면 다음 모든 검증이 전달됩니다.
@autowired Private Validator Validator; @requestmapping ( "/demo3") public void demo3 () {demo2 demo2 = new demo2 (); demo2.setage ( "111"); Demo2.Sethigh (150); demo2.setlength ( "abcde"); demo2.setList (new arrayList <string> () {{add ( "111"); add ( "222"); add ( "333");}}); set <constraintViolation <demo2 >> violationset = validator.validate (demo2); for (제약 범위 <edo2> 모델 : ViolationSet) {System.out.println (model.getMessage ()); }}4. 객체 캐스케이드 검증
객체에는 다른 객체가 속성으로 다른 개체가 포함되어 있으며 속성에 @valid를 추가하여 객체 내부의 확인을 속성으로 확인합니다. (Demo2 예를 확인할 때 Demo2의 필드를 확인할 수 있습니다).
@datapublic class demo2 {@size (min = 3, max = 5, message = "목록의 크기는 [3,5]") 개인 목록 <string> 목록; @notnull @valid private demo3 demo3;} @datapublic class demo3 {@length (min = 5, max = 17, message = "길이 길이는 [5,17]") 개인 문자열 Extfield;}캐스케이드 검증 :
/ ** Bean은 빠른 고장 반환 Bean*/ @autowired Private Validator Validator로 구성됩니다. @requestmapping ( "/demo3") public void demo3 () {demo2 demo2 = new demo2 (); demo2.setList (new arrayList <string> () {{add ( "111"); add ( "222"); add ( "333");}}); demo3 demo3 = 새로운 demo3 (); demo3.setextfield ( "22"); demo2.setdemo3 (demo3); set <constraintViolation <demo2 >> violationset = validator.validate (demo2); for (제약 범위 <edo2> 모델 : ViolationSet) {System.out.println (model.getMessage ()); }}Demo3의 Extfield 필드를 확인할 수 있습니다.
5. 그룹 검증
결론 : 그룹화 시퀀스를 확인할 때 지정된 그룹화 순서로 확인하십시오. 이전 확인이 실패하면 후속 그룹화를 확인할 수 없습니다.
새 사용자 정보가 추가되면 userID를 확인할 필요가없는 시나리오가 있습니다 (시스템이 생성되기 때문에). 수정할 때 userId는 userID를 확인해야하며 사용자의 검증 기능을 유효성 검사기로 검증 할 수 있습니다.
유효성 검사 모드 ( "Hibernate.validator.fail_fast", "false")로 유효성 검사기를 설정하고 검증 그룹, GroupB 및 Model을 사용하십시오.
Groupa, GroupB : Public Interface Groupa {} public interface groupb {}모델 확인 : 사람
@datapublic 클래스 개인 {@notblank @Range (min = 1, max = integer.max_value, message = "0보다 클 사람", groups = {groupa.class}) / ** 사용자 ID* / private intger userId; @notblank @length (min = 4, max = 20, message = "[4,20]에 있어야합니다. @NotBlank @Range (min = 0, max = 100, message = "나이는 [0,100]에 있어야합니다. @Range (min = 0, max = 2, message = "성별은 [0,2]에 있어야합니다. 1 : 남성; 2 : 여성*/ 개인 정수 섹스;}위의 직접 표시된 바와 같이, 세 그룹은 각각 다음과 같이 검증됩니다.
에이. 그룹화
Groupa 및 GroupB 태그의 그룹 만 확인됩니다.
@requestmapping ( "/demo5") public void demo5 () {person p = new person (); / ** groupa 검증이 통과되지 않습니다*/ p.setuserid (-12); /** Groupa Verification Pass*//p.setuserid(12); p.setusername ( "a"); P. 세트 (110); P. 세트 섹스 (5); set <constraintViolation <person>> validate = validator.validate (p, groupa.class, groupb.class); for (제약 범위화 <person> 항목 : Validate) {System.out.println (항목); }}또는
@requestmapping ( "/demo6") public void demo6 (@validated ({groupa.class, groupb.class}) person p, bindingResult result) {if (result.haserrors ()) {list <objecterror> allerrors = result.getallerrors (); for (objecterror error : allerrors) {system.out.println (오류); }}}Groupa, GroupB 및 Default가 검증되지 않은 경우 :
확인 정보는 다음과 같습니다.
ranksaintViolationImpl {interpolatedMessage = '[4,20]', propertypath = username, rootbeanclass = class validator.demo.project.model.person, messagetemplate = '[4,20]'}} constraintViolationimpl {interpolatedMessage = ', expressid =', root -polatedmessage = ' validator.demo.project.model.person, messagetemplate = '0'}} 제한적 ViolationImpl {interpolatedMessage = 'Gender는 [0,2]', propertypath = sex, rootbeanclass = class validator.demo.project.model.person, messagetemplater = [0] 'in in in.Groupa 확인이 전달되면 GroupB 및 기본 확인이 전달되지 않습니다.
확인 정보는 다음과 같습니다.
ConstraintViolationImpl {interpolatedMessage = '[4,20]', propertypath = username, rootbeanclass = class validator.demo.project.model.person, messagetemplate = '에 있어야합니다. rootbeanclass = class validator.demo.project.model.person, messagetemplate = '성별이 [0,2]' '}에 있어야합니다.비. 그룹 시퀀스
그룹 별 확인 여부를 지정하는 것 외에도 그룹의 확인 순서를 지정할 수도 있습니다. 이전 그룹의 검증이 실패하면 다음 그룹의 검증이 수행되지 않습니다.
지정된 그룹의 시퀀스 (Groupa》 groupb》 기본값) :
@GroupEdgeence ({groupa.class, groupb.class, default.class}) public interface grouporder {}테스트 데모 :
@requestmapping ( "/demo7") public void demo7 () {person p = new person (); /** groupa 확인은*///p.setuserid (10)를 통과하지 못합니다. / ** groupa verification pass*/ p.setuserid (12); p.setusername ( "a"); P. 세트 (110); P. 세트 섹스 (5); set <constraintViolation <person>> validate = validator.validate (p, grouporder.class); for (제약 범위화 <person> 항목 : Validate) {System.out.println (항목); }}또는
@requestmapping ( "/demo8") public void demo8 (@validated ({grouporder.class}) person p, bindingResult result) {if (result.haserrors ()) {list <sbjecterror> allerrors = result.getallerrors (); for (objecterror error : allerrors) {system.out.println (오류); }}}Groupa, GroupB 및 Default가 검증되지 않은 경우 :
확인 정보는 다음과 같습니다.
chanstaintViolationImpl {interpolatedMessage = '는 0', propertypath = userID, rootBeanClass = class validator.demo.project.Model.Person, MessagetEmplate = '0'}보다 커야합니다.Groupa 확인이 전달되면 GroupB 및 기본 확인이 전달되지 않습니다.
확인 정보는 다음과 같습니다.
ConstraintViolationImpl {interpolatedMessage = '[4,20]', propertypath = username, rootbeanclass = class validator.demo.project.model.person, messagetemplate = '에 있어야합니다. rootbeanclass = class validator.demo.project.model.person, messagetemplate = '성별이 [0,2]' '}에 있어야합니다.결론 : 그룹화 시퀀스를 확인할 때 지정된 그룹화 순서로 확인하십시오. 이전 확인이 실패하면 후속 그룹화를 확인할 수 없습니다.
5. 사용자 정의 검증 자
일반적으로 사용자 정의 검증은 많은 문제를 해결할 수 있습니다. 그러나 상황을 충족시킬 수없는 경우도 있습니다. 현재 Validator 인터페이스를 구현하고 필요한 유효성 검사기를 사용자 정의 할 수 있습니다.
아래와 같이, 사용자 정의 케이스 유효성 검사기가 구현됩니다.
public enum casemode {upper, lower;}@target ({elementtype.method, elementtype.field, elementtype.annotation_type})@retention (rendentionpolicy.runtime) @constraint (validatedby = checkcasevalidator.class) @documentedpublic @interface checkcese {) default ""; class <?> [] groups () default {}; 클래스 <? payload> [] payload () default {}을 확장합니다. casemode value ();} public class checkcasevalidator는 구속 조건 Validator <checkcase, string> {private casemode casemode; public void initialize (checkcase checkcase) {this.casemode = checkcase.value (); } public boolean isvalid (String s, supstaintValidatorContext restaintValidatorContext) {if (s == null) {return true; } if (casemode == casemode.upper) {return s.equals (s.toupperCase ()); } else {return s.equals (s.tolowercase ()); }}}확인하는 모델 :
public class demo {@checkcase (value = casemode.lower, message = "사용자 이름은 소문자 여야합니다") 개인 문자열 사용자 이름; public String getUserName () {return username; } public void setusername (String username) {this.username = username; }}유효성 검사 구성 :
@Bean public validator validator () {validatorFactory validatorFactory = validation.ByProvider (hibernateValidator.class) .configure () .addproperty ( "hibernate.validator.fail_fast", "true") .BuildValidatorfactory (); Validator Validator = validatorfactory.getValidator (); 반환 유효성 검사기; }확인 테스트 :
@requestmapping ( "/demo4") public void demo4 () {demo demo = new demo (); demo.setusername ( "사용자 이름"); set <constraintViolation <demo >> validate = validator.validate (demo); for (제한적 <memo : validate) {system.out.println (dem.getMessage ()); }}출력 결과 :
사용자 이름은 소문자 여야합니다
6. 일반적인 주석
The built-in constraint in Bean Validation @Null The annotated element must be null @NotNull The annotated element must not be null @AssertTrue The annotated element must be true @AssertFalse The annotated element must be false @Min(value) The annotated element must be a number, its value must be greater than or equal to the specified minimum value @Max(value) The annotated element must be a number, its value must be less than or equal 지정된 최대 값 @decimalmin (값)에 주석이 붙은 요소는 숫자 여야합니다. 값은 지정된 최소값 @decimalMax (값)에 값이 높아야합니다. 주석이 붙은 요소는 숫자가 숫자보다 낮아야합니다. 값은 지정된 최대 값 @size (max =, min =)와 같아야합니다 (max =, min =). 숫자와 그 값은 수용 가능한 범위 내에 있어야합니다 @past 주석이 붙은 요소는 과거 날짜 여야합니다. @length (min =, max =) 주석이 붙은 문자열은 지정된 범위 내에 있어야합니다. @notempty 주석이없는 문자열은 @Range (min =, max =, message =) 여야합니다. 주석이없는 요소는 0.01 @notnull @decimalmin (valsue = "0.01을 포함하여 0.01 @notnull @moge @false)을 포함하지 않아야합니다. 0.01@notnull@decimalmin (value = "0.01", = true) private bigdecimal greatorequalthan; @length (min = 1, max = 20, max = "message nake level a vimile") // 길이를 범위로 사용할 수 없습니다 //@range (min = 1, max = "message ="message = "message ="message = "message ="message = "private string message;
7. 참조 자료
참조 :
http://docs.jboss.org/hibernate/validator/4.2/reference/zh-cn/html_single/#validator-gettingstarted