日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Hibernate Validator 总结大全

發布時間:2023/12/16 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hibernate Validator 总结大全 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背景

代碼開發過程中,參數的有效性校驗是一項很繁瑣的工作, 如果參數簡單,就那么幾個參數,直接通過ifelse可以搞定,如果參數太多,比如一個大對象有100多個字段作為入參,你如何校驗呢? 仍使用ifelse就是體力活了, Hibernate Validator 是很好的選擇。

官方文檔入口: https://hibernate.org/validator/

文章示例基于6.0版本,可以參考6.0的官方文檔:https://docs.jboss.org/hibernate/validator/6.0/reference/en-US/html_single/#validator-gettingstarted

掃碼查看原文:

maven依賴

Hibernate validator 依賴

<!-- hibernate validator --> <dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId><version>6.0.13.Final</version> </dependency> <dependency><groupId>javax.el</groupId><artifactId>javax.el-api</artifactId><version>3.0.1-b06</version> </dependency> <dependency><groupId>org.glassfish.web</groupId><artifactId>javax.el</artifactId><version>2.2.6</version> </dependency>

為了能讓示例代碼跑起來的一些必要依賴

<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.8</version><scope>provided</scope> </dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version> </dependency>

支持的校驗注解

javax.validation.constraints 包下面的校驗注解都支持,如下面這些注解,基本上見名知意, 就不一一解釋了

Max 最大值校驗 Min 最小值校驗 Range 范圍校驗,Min和Max的組合 NotBlank 不為空白字符的校驗 NotEmpty 數組、集合等不為空的校驗 NotNull 空指針校驗 Email 郵箱格式校驗 ....

下面通過示例代碼來說明校驗器常用的幾種使用方式: 簡單對象校驗、分組校驗、

簡單對象校驗

建一個需要檢驗的參數類:

@Data public class SimpleBean {@NotBlank(message = "姓名不能為空")private String name;@NotNull(message = "年齡不能為空")@Range(min = 0, max = 100, message = "年齡必須在{min}和{max}之間")private Integer age;@NotNull(message = "是否已婚不能為空")private Boolean isMarried;@NotEmpty(message = "集合不能為空")private Collection collection;@NotEmpty(message = "數組不能為空")private String[] array;@Emailprivate String email;/*真實場景下面可能還有幾十個字段省略 ... ...*/}

校驗測試

public class ValidateTest {//初始化一個校驗器工廠 private static ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure()//校驗失敗是否立即返回: true-遇到一個錯誤立即返回不在往下校驗,false-校驗完所有字段才返回.failFast(false).buildValidatorFactory();Validator validator = validatorFactory.getValidator();/*** 簡單對象校驗*/@Testpublic void testSimple() {SimpleBean s=new SimpleBean();s.setAge(5);s.setName(" ");s.setEmail("email");Set<ConstraintViolation<SimpleBean>> result=validator.validate(s);System.out.println("遍歷輸出錯誤信息:");//getPropertyPath() 獲取屬性全路徑名//getMessage() 獲取校驗后的錯誤提示信息result.forEach(r-> System.out.println(r.getPropertyPath()+":"+r.getMessage()));} }

測試結果

遍歷輸出錯誤信息: email:不是一個合法的電子郵件地址 collection:集合不能為空 array:數組不能為空 name:姓名不能為空 isMarried:是否已婚不能為空

嵌套對象校驗

嵌套對象

上面是簡單對象的校驗,我們來嘗試嵌套對象的校驗,類結構如下:

|--OrgBean |----EmployeeBean |------List<PersonBean>

OrgBean.java代碼,對于嵌套對象校驗要注意, 需要在內部引用的對象上用到@Valid注解,否則不會校驗被引用對象的內部字段

@Data public class OrgBean {@NotNullprivate Integer id;@Valid //如果此處不用Valid注解,則不會去校驗EmployeeBean對象的內部字段 @NotNull(message = "employee不能為空")private EmployeeBean Employee; }

EmployeeBean.java代碼

@Data public class EmployeeBean {@Valid@NotNull(message = "person不能為空")/*** 此處用到容器元素級別的約束: List<@Valid @NotNull PersonBean> * 會校驗容器內部元素是否為null,否則為null時會跳過校驗* NotNull注解的target包含ElementType.TYPE_USE,因此NotNull可以給泛型注解*/private List<@Valid @NotNull PersonBean> people; }

PersonBean.java

@Data public class PersonBean {@NotBlank(message = "姓名不能為空")private String name;@NotNull(message = "年齡不能為空")@Range(min = 0, max = 100, message = "年齡必須在{min}和{max}之間")private Integer age;@NotNull(message = "是否已婚不能為空")private Boolean isMarried;@NotNull(message = "是否有小孩不能為空")private Boolean hasChild;@NotNull(message = "小孩個數不能為空")private Integer childCount;@NotNull(message = "是否單身不能為空")private Boolean isSingle;}

校驗測試代碼

@Test public void testNested() {PersonBean p=new PersonBean();p.setAge(30);p.setName("zhangsan");//p.setIsMarried(true);PersonBean p2=new PersonBean();p2.setAge(30);//p2.setName("zhangsan2");p2.setIsMarried(false);//p2.setHasChild(true);OrgBean org=new OrgBean();//org.setId(1);List<PersonBean> list=new ArrayList<>();list.add(p);list.add(p2);//增加一個null,測試是否會校驗元素為nulllist.add(null);EmployeeBean e=new EmployeeBean();e.setPeople(list);org.setEmployee(e);Set<ConstraintViolation<OrgBean>> result=validator.validate(org);System.out.println("遍歷輸出錯誤信息:");result.forEach(r-> System.out.println(r.getPropertyPath()+":"+r.getMessage()));}

測試結果

id:不能為null Employee.people[0].childCount:小孩個數不能為空 Employee.people[0].isSingle:是否單身不能為空 Employee.people[1].hasChild:是否有小孩不能為空 Employee.people[0].isMarried:是否已婚不能為空 Employee.people[1].name:姓名不能為空 Employee.people[1].childCount:小孩個數不能為空 Employee.people[2].<list element>:不能為null Employee.people[0].hasChild:是否有小孩不能為空 Employee.people[1].isSingle:是否單身不能為空

結果分析:
(1)可以看到打印結果中校驗的屬性名有一長串: Employee.people[0].childCount
這是由于ConstraintViolation.getPropertyPath()函數返回的是屬性的全路徑名稱。
(2)還有List元素中的值為null也進行了校驗:Employee.people[2].:不能為null
這是因為使用了容器元素級別的校驗,這種校驗器可以使用在泛型參數里面,如注解在List元素的泛型里面增加@NotNull注解: private List<@Valid @NotNull PersonBean> people;
如果沒有該注解,則list.dd(null)添加的空指針元素不會被校驗。

/*** 此處用到容器元素級別的約束 List<@Valid @NotNull PersonBean> 會校驗容器內部元素是否為null,否則為null時會跳過校驗* NotNull注解的target包含ElementType.TYPE_USE,因此NotNull可以給泛型注解*/ private List<@Valid @NotNull PersonBean> people;

Hibernate Validator 約束級別

(1)字段級別: 在字段上面添加校驗注解
本質上就是可以添加在字段上的注解,@Target({ElementType.FIELD})。

(2)屬性級別: 在方法上面添加注解,如注解在getName()方法上
本質上就是可以添加在方法上的注解,@Target({ElementType.METHOD}) 。

(3)容器級別:在容器里面添加注解
本質上就是可以添加在泛型上的注解,這個是java8新增的特性,@Target({ElementType.TYPE_USE})。
如這些類都可以支持容器級別的校驗:java.util.Iterable實現類,java.util.Map的key和values,java.util.Optional,java.util.OptionalInt,java.util.OptionalDouble,java.util.OptionalLong 等, 如:
List<@Valid @NotNull PersonBean> people;
private Map<@Valid Part, List<@Valid Manufacturer>> partManufacturers;

(4)類級別:添加在類上面的校驗注解
需要@Target({ElementType.TYPE})標注,當然如果有@Target({ElementType.TYPE_USE})也行,因為TYPE_USE包含TYPE。

分組校驗

有這樣一個需求:當People對象為已婚時(isMarried字段為true),需要校驗”配偶姓名“、”是否有小孩“等字段不能為空,當People對象為未婚時,需要校驗“是否單身”等其他字段不能為空, 這種需求可以通過分組檢驗來實現,將校驗邏輯分為兩個組,然后每次調用校驗接口時指定分組即可實現不同的校驗。 如果不管“是否已婚”都需要校驗的字段(如姓名、年齡這些字段等),則可以同時指定兩個分組。

靜態分組

靜態分組主要在類上面是使用GroupSequence注解指定一個或者多個分組,用于處理不同的校驗邏輯,我覺得這個基本上是寫死的不能更改,用不用分組區別不大,因此沒什么好說的,可以跳過直接看后面的動態分組。

@GroupSequence({ Group.UnMarried.class, Group.Married.class }) public class RentalCar extends PeopleBean {... ... }

動態分組

“未婚”和“已婚”兩個分組的代碼如下,由于分組必須是一個Class,而且有沒有任何實現只是一個標記而已,因此我可以用接口。

public interface Group {//已婚情況的分組校驗interface Married {}//未婚情況的分組校驗interface UnMarried {}}

校驗對象:People2Bean.java

@Data public class People2Bean {//不管是否已婚,都需要校驗的字段,groups里面指定兩個分組@NotBlank(message = "姓名不能為空",groups = {Group.UnMarried.class, Group.Married.class})private String name;@NotNull(message = "年齡不能為空",groups = {Group.UnMarried.class, Group.Married.class})@Range(min = 0, max = 100, message = "年齡必須在{min}和{max}之間",groups = {Group.UnMarried.class, Group.Married.class})private Integer age;@NotNull(message = "是否已婚不能為空",groups = {Group.UnMarried.class, Group.Married.class})private Boolean isMarried;//已婚需要校驗的字段@NotNull(message = "配偶姓名不能為空",groups = {Group.Married.class})private String spouseName;//已婚需要校驗的字段@NotNull(message = "是否有小孩不能為空",groups = {Group.Married.class})private Boolean hasChild;//未婚需要校驗的字段@NotNull(message = "是否單身不能為空",groups = {Group.UnMarried.class})private Boolean isSingle; }

測試代碼:通過isMarried的值來動態指定分組校驗

@Test public void testGroup() {PeopleBean p=new PeopleBean();p.setAge(30);p.setName(" ");p.setIsMarried(false);Set<ConstraintViolation<PeopleBean>> result;//通過isMarried的值來動態指定分組校驗if(p.getIsMarried()){//如果已婚,則按照已婚的分組字段result=validator.validate(p, Group.Married.class);}else{//如果未婚,則只校驗未婚的分組字段result=validator.validate(p, Group.UnMarried.class);}System.out.println("遍歷輸出錯誤信息:");result.forEach(r-> System.out.println(r.getPropertyPath()+":"+r.getMessage())); }

測試結果,可以發現,未婚校驗了isSingle字段,符合預期

遍歷輸出錯誤信息: name:姓名不能為空 isSingle:是否單身不能為空

將上述代碼中的isMarried設置為true:p.setIsMarried(false) 再次執行結果如下,也是符合預期的

遍歷輸出錯誤信息: name:姓名不能為空 hasChild:是否有小孩不能為空 spouseName:配偶姓名

動態分組優化

有沒有發現上面的分組校驗代碼實現不夠好?本來校驗我是要完全交給validator框架的,但是我還得在校驗框架之外面額外判斷isMarried再來決定校驗方式(如下代碼),這樣校驗代碼從校驗框架外泄了,不太優雅,有沒有優化的空間呢?

if(p.getIsMarried()){//如果已婚,則按照已婚的分組字段result=validator.validate(p, Group.Married.class); }else{//如果未婚,則只校驗未婚的分組字段result=validator.validate(p, Group.UnMarried.class); }

其實通過DefaultGroupSequenceProvider接口可以優化,這才是真正的動態分組校驗,在該接口實現中判斷isMarried值,來實現動態設置分組,也就是將校驗的額外判斷邏輯從校驗框架外層轉移到了校驗框架中,外層業務代碼只需要調用校驗接口即可,而無需關注具體的校驗邏輯,這樣的框架才是優秀的。

如下PeopleGroupSequenceProvider.java類實現了DefaultGroupSequenceProvider接口

public class PeopleGroupSequenceProvider implements DefaultGroupSequenceProvider<People2Bean> {@Overridepublic List<Class<?>> getValidationGroups(People2Bean bean) {List<Class<?>> defaultGroupSequence = new ArrayList<>();// 這里必須將校驗對象的類加進來,否則沒有Default分組會拋異常,這個地方還沒太弄明白,后面有時間再研究一下 defaultGroupSequence.add(People2Bean.class);if (bean != null) {Boolean isMarried=bean.getIsMarried();///System.err.println("是否已婚:" + isMarried + ",執行對應校驗邏輯");if(isMarried!=null){if(isMarried){System.err.println("是否已婚:" + isMarried + ",groups: "+Group.Married.class);defaultGroupSequence.add(Group.Married.class);}else{System.err.println("是否已婚:" + isMarried + ",groups: "+Group.UnMarried.class);defaultGroupSequence.add(Group.UnMarried.class);}}else {System.err.println("isMarried is null");defaultGroupSequence.add(Group.Married.class);defaultGroupSequence.add(Group.UnMarried.class);}}else{System.err.println("bean is null");}return defaultGroupSequence;} }

People2Bean.java類上要用到@GroupSequenceProvider注解指定一個GroupSequenceProvider

@GroupSequenceProvider(PeopleGroupSequenceProvider.class) public class People2Bean {//字段同上 //... ... }

測試代碼

@Test public void testGroupSequence(){People2Bean p=new People2Bean();p.setAge(30);p.setName(" ");System.out.println("----已婚情況:");p.setIsMarried(true);Set<ConstraintViolation<People2Bean>> result=validator.validate(p);System.out.println("遍歷輸出錯誤信息:");result.forEach(r-> System.out.println(r.getPropertyPath()+":"+r.getMessage()));System.out.println("----未婚情況:");p.setIsMarried(false);result=validator.validate(p);System.out.println("遍歷輸出錯誤信息:");result.forEach(r-> System.out.println(r.getPropertyPath()+":"+r.getMessage()));}

測試結果符合預期

----已婚情況: 遍歷輸出錯誤信息: name:姓名不能為空 spouseName:配偶姓名不能為空 hasChild:是否有小孩不能為空 ----未婚情況: 遍歷輸出錯誤信息: name:姓名不能為空 isSingle:是否單身不能為空

自定義校驗器

Hibernate中有不少約束校驗器,但是不一定能滿足你的業務,因此它還支持自定義約束校驗器,一般是一個約束注解配合一個校驗器使用,校驗器需要實現ConstraintValidator接口,然后約束注解中通過`@Constraint(validatedBy = {ByteLengthValidator.class})綁定校驗器即可。 這里我寫三個示例來說明:

自定義枚舉校驗

在開發過程中,有很多參數類型限制只能使用某些枚舉值,我們可以通過自定義的校驗器來做約束,以最簡單的性別舉例,在我國性別只有男和女,校驗注解定義如下: EnumRange.java

@Documented @Constraint(//這個配置用于綁定校驗器:EnumRangeValidatorvalidatedBy = {EnumRangeValidator.class} ) @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE}) @Retention(RetentionPolicy.RUNTIME) @Repeatable(EnumRange.List.class) public @interface EnumRange {//自定義默認的消息模板String message() default "枚舉值不正確,范圍如下:{}";//枚舉類,用于在校驗器中限定值的范圍Class<? extends Enum> enumType();//分組 Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})@Retention(RetentionPolicy.RUNTIME)@Documented//支持數組校驗public @interface List {EnumRange[] value();} }

校驗器類:EnumRangeValidator.java 實現 ConstraintValidator 接口, ConstraintValidator<EnumRange,String> 接口的第一個泛型參數綁定EnumRange注解,第二個參數綁定要校驗的值類型,這里是String。

public class EnumRangeValidator implements ConstraintValidator<EnumRange,String> {private Set<String> enumNames;private String enumNameStr;@Overridepublic void initialize(EnumRange constraintAnnotation) {Class<? extends Enum> enumType=constraintAnnotation.enumType();if(enumType==null){throw new IllegalArgumentException("EnumRange.enumType 不能為空");}try {//初始化:將枚舉值放到Set中,用于校驗Method valuesMethod = enumType.getMethod("values");Enum[] enums = (Enum[]) valuesMethod.invoke(null);enumNames = Stream.of(enums).map(Enum::name).collect(Collectors.toSet());enumNameStr = enumNames.stream().collect(Collectors.joining(","));} catch (Exception e) {throw new RuntimeException("EnumRangeValidator 初始化異常",e);}}@Overridepublic boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {if(value==null){return true;}boolean result = enumNames.contains(value);if(!result){//拿到枚舉中的message,并替換變量,這個變量是我自己約定的,//你在使用注解的message中有花括號,這里會被替換為用逗號隔開展示的枚舉值列表String message = constraintValidatorContext.getDefaultConstraintMessageTemplate().replace("{}",enumNameStr);//禁用默認值,否則會有兩條messageconstraintValidatorContext.disableDefaultConstraintViolation();//添加新的messageconstraintValidatorContext.buildConstraintViolationWithTemplate(message).addConstraintViolation();}return result;} }

我們來定義一個性別的枚舉:當然,你還可以用其他自定義枚舉,只要是枚舉值這個校驗就就能生效

public enum SexEnum {F("女"),M("男");String desc;SexEnum(String desc){this.desc=desc;}}

被校驗的類:Person2Bean.java

@Data public class Person2Bean {@NotBlank(message = "姓名不能為空")private String name;@Range(min = 0, max = 100, message = "年齡必須在{min}和{max}之間")private Integer age;//性別用到上面的自定義注解,并指定枚舉類SexEnum,message模板里面約定變量綁定“{}” @EnumRange(enumType = SexEnum.class, message = "性別只能是如下值:{}")private String sex;}

校驗測試代碼

@Test public void testSelfDef() {Person2Bean s=new Person2Bean();//性別設置為“A",校驗應該不通過 s.setSex("A");//s.setFriendNames(Stream.of("zhangsan","李四思").collect(Collectors.toList()));Set<ConstraintViolation<Person2Bean>> result=validator.validate(s);System.out.println("遍歷輸出錯誤信息:");result.forEach(r-> System.out.println(r.getPropertyPath()+":"+r.getMessage())); }

校驗結果如下:性別設置為“A",校驗應該不通過不是枚舉值中的F和M,因此符合預期

遍歷輸出錯誤信息: sex:性別只能是如下值:F,M name:姓名不能為空

自定義字節數校驗器

參數的字段值要存入數據庫,比如某個字段用的 Oracle 的 Varchar(4) 類型,那么該字段值的不能超過4個字節,一般可能會想到應用 @Length 來校驗,但是該校驗器校驗的是字符字符串長度,即用 String.length() 來校驗的,英文字母占用的字節數與String.length()一致沒有問題,但是中文不行,根據不同的字符編碼占用的字節數不一樣,比如一個中文字符用UTF8占用3個字節,用GBK占用兩個字節,而一個英文字符不管用的什么編碼始終只占用一個字節,因此我們來創建一個字節數校驗器。

校驗注解類:ByteMaxLength.java

@Documented //綁定校驗器:ByteMaxLengthValidator @Constraint(validatedBy = {ByteMaxLengthValidator.class}) @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE}) @Retention(RetentionPolicy.RUNTIME) @Repeatable(ByteMaxLength.List.class) public @interface ByteMaxLength {//注意這里的max是指最大字節長度,而非字符個數,對應數據庫字段類型varchar(n)中的nint max() default Integer.MAX_VALUE;String charset() default "UTF-8";Class<?>[] groups() default {};String message() default "【${validatedValue}】的字節數已經超過最大值{max}";Class<? extends Payload>[] payload() default {};@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface List {ByteMaxLength[] value();} }

校驗最大字節數的校驗器:ByteMaxLengthValidator.java ,注意里面約定了兩個綁定變量:chMax 和 enMax,分別對應中、英文的最大字符數,用于message模板中使得錯誤提示更加友好

public class ByteMaxLengthValidator implements ConstraintValidator<ByteMaxLength,String> {private int max;private Charset charset;@Overridepublic void initialize(ByteMaxLength constraintAnnotation) {max=constraintAnnotation.max();charset=Charset.forName(constraintAnnotation.charset());}@Overridepublic boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {if(value==null){return true;}int byteLength = value.getBytes(charset).length;//System.out.println("byteLength="+byteLength);boolean result = byteLength<=max;if(!result){//這里隨便用一個漢字取巧獲取每個中文字符占用該字符集的字節數int chBytes = "中".getBytes(charset).length;System.out.println("chBytes="+chBytes);//計算出最大中文字數int chMax = max/chBytes;//拿到枚舉中的message,并替換變量,這個變量是我自己約定的,//約定了兩個綁定變量:chMax 和 enMaxString message = constraintValidatorContext.getDefaultConstraintMessageTemplate().replace("{chMax}",String.valueOf(chMax)).replace("{enMax}",String.valueOf(max));//禁用默認值,否則會有兩條messageconstraintValidatorContext.disableDefaultConstraintViolation();//添加新的messageconstraintValidatorContext.buildConstraintViolationWithTemplate(message).addConstraintViolation();}return result;} }

校驗類

@Data public class Person2Bean {/*** message里面用到了前面約定的兩個變量:chMax和enMax,* 至于${validatedValue}是框架內置的變量,用于獲取當前被校驗對象的值*/@ByteMaxLength(max=4,charset = "UTF-8", message = "姓名【${validatedValue}】全中文字符不能超過{chMax}個字,全英文字符不能超過{enMax}個字母")private String name;/*** 該注解可以用于泛型參數:List<String> ,* 這樣可以校驗List中每一個String元素的字節數是否符合要求*/private List<@ByteMaxLength(max=4,charset = "UTF-8",message = "朋友姓名【${validatedValue}】的字節數不能超過{max}")String> friendNames;@Range(min = 0, max = 100, message = "年齡必須在{min}和{max}之間")private Integer age;//@EnumRange(enumType = SexEnum.class, message = "性別只能是如下值:{}")private String sex;}

校驗測試代碼

@Test public void testSelfDef() {Person2Bean s=new Person2Bean();s.setName("張三");//s.setSex("M");s.setFriendNames(Stream.of("zhangsan","李四思","張").collect(Collectors.toList()));Set<ConstraintViolation<Person2Bean>> result=validator.validate(s);System.out.println("遍歷輸出錯誤信息:");result.forEach(r-> System.out.println(r.getPropertyPath()+":"+r.getMessage())); }

運行結果,可以發現List中的元素也可以校驗

遍歷輸出錯誤信息: name:姓名【張三】全中文字符不能超過1個字,全英文字符不能超過4個字母 friendNames[0].<list element>:朋友姓名【zhangsan】的字節數不能超過4 friendNames[1].<list element>:朋友姓名【李四思】的字節數不能超過4

由于上面用的UTF-8編碼,max=4,中文占三個字節,因此只能一個中文字符,換成GBK試一下

@ByteMaxLength(max=4,charset = "GBK", message = "姓名【${validatedValue}】全中文字符不能超過{chMax}個字,全英文字符不能超過{enMax}個字母") private String name;//可以用于校驗數組元素:List<String> private List<@ByteMaxLength(max=4,charset = "GBK",message = "朋友姓名【${validatedValue}】的字節數不能超過{max}")String> friendNames;

同樣的測試代碼發現校驗結果不一樣了:name="張三"校驗通過了,由于GBK中文值占2個字節而不是3個字節

friendNames[1].<list element>:朋友姓名【李四思】的字節數不能超過4 friendNames[0].<list element>:朋友姓名【zhangsan】的字節數不能超過4

自定義類級別的校驗器

類級別的校驗器沒什么特別的,無非是其可以注解到類上面,即由@Target({ElementType.TYPE})標注的注解。但是某些特殊場景非常有用,字段上的校驗器只能用于校驗單個字段,如果我們需要對多個字段進行特定邏輯的組合校驗就非常有用了。

下面的示例用于校驗:訂單價格==商品數量*商品價格

@OrderPrice注解:OrderPrice.java

@Documented //綁定校驗器 @Constraint(validatedBy = {OrderPriceValidator.class}) //可以發現沒有 ElementType.TYPE 該注解也能用到類上面,這是因為ElementType.TYPE_USE包含ElementType.TYPE @Target({ElementType.TYPE_USE, ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Repeatable(OrderPrice.List.class) public @interface OrderPrice {Class<?>[] groups() default {};String message() default "訂單價格不符合校驗規則";Class<? extends Payload>[] payload() default {};@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface List {OrderPrice[] value();} }

校驗器: OrderPriceValidator.java,注意ConstraintValidator<OrderPrice, OrderBean>第二個泛型參數為被校驗的類OrderBean

public class OrderPriceValidator implements ConstraintValidator<OrderPrice, OrderBean> {@Overridepublic void initialize(OrderPrice constraintAnnotation) {}@Overridepublic boolean isValid(OrderBean order, ConstraintValidatorContext constraintValidatorContext) {if(order==null){return true;}return order.getPrice()==order.getGoodsPrice()*order.getGoodsCount();}}

被校驗類:OrderBean.java

@Data //類上面用到自定義的校驗注解 @OrderPrice public class OrderBean {@NotBlank(message = "商品名稱不能為空")private String goodsName;@NotNull(message = "商品價格不能為空")private Double goodsPrice;@NotNull(message = "商品數量不能為空")private Integer goodsCount;@NotNull(message = "訂單價格不能為空")private Double price;@NotBlank(message = "訂單備注不能為空")private String remark;}

校驗測試代碼

@Test public void testSelfDef2() {OrderBean o=new OrderBean();o.setGoodsName("辣條");o.setGoodsCount(5);o.setGoodsPrice(1.5);o.setPrice(20.5);Set<ConstraintViolation<OrderBean>> result=validator.validate(o);System.out.println("遍歷輸出錯誤信息:");result.forEach(r-> System.out.println(r.getPropertyPath()+":"+r.getMessage())); }

測試執行結果如下:符合預期

遍歷輸出錯誤信息: :訂單價格不符合校驗規則 remark:訂單備注不能為空

EL表達式

其實在上面的示例中,可以看到在message中已經使用到了EL表達式:

@ByteMaxLength(max=4,charset = "GBK", message = "姓名【${validatedValue}】全中文字符不能超過{chMax}個字,全英文字符不能超過{enMax}個字母")private String name;

包含在${與}之間的就是EL表達式,比如這里的${validatedValue} , validatedValue是內置的變量,用于存儲當前被校驗對象的值,更復雜的用法不僅僅是取值,還可以做各種邏輯運算、內置函數調用等,如下面這些用法:

@Size(min = 2,max = 14,message = "The license plate '${validatedValue}' must be between {min} and {max} characters long" )@Min(value = 2,message = "There must be at least {value} seat${value > 1 ? 's' : ''}" )DecimalMax(value = "350",message = "The top speed ${formatter.format('%1$.2f', validatedValue)} is higher than {value}" )@DecimalMax(value = "100000", message = "Price must not be higher than ${value}")

上面有一種不包含$符號,只包含在花括號{}的表達式,這種表達式只能用于簡單的變量替換,如果沒有該變量也不會報錯,只是會被原樣輸出,而${validatedValue}這個里面的表達式如果錯了則會拋異常。

比如@Length注解有兩個變量min和max,其實像groups、payload都可以獲取到其值,也就是在message中可以獲取當前注解的所有成員變量值(除了message本身)。

public @interface Length {int min() default 0;int max() default 2147483647;String message() default "{org.hibernate.validator.constraints.Length.message}";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};... ... }

如:

@Length(min=1,max=10,message = "字符長度請控制在{min}到{max}之間,分組校驗:{groups},消息:{message}") private String name;

上述代碼的message中{min}、{max}、{groups}最終在錯誤消息輸出時hi可以被對應的變量值替換的,但是{message}就會被原樣輸出,因為不可能在message里面獲取它自己的值。

校驗框架對EL表達式的支持對于自定義消息模板非常有用,可以使錯誤消息提示更加友好。

SpringMVC中如何使用

上面的示例代碼都是在單元測試中使用,validator類也是自己手動創建的,在spring中validator需要通過容器來創建,除了上面的maven依賴,還需在spring.xml中為校驗器配置工廠bean

<mvc:annotation-driven validator="validator"/> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"><property name="providerClass" value="org.hibernate.validator.HibernateValidator"/><property name="validationMessageSource" ref="messageSource"/> </bean><bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">

然后在Controller類中方法的參數增加@Valid注解即可

@RequestMapping("/update") public String update(@Valid PersonBean person) {//TODO ... }

總結

寫到這里,上面提到的validator框架用法基本能滿足我們大多數業務場景了,我是最近在為公司寫業務代碼過程中對各種繁瑣的校驗頭痛不已,前期都是直接用ifelse搞定,后面覺得干體力活沒意思,因此通過validator框架把公司代碼現有校驗邏輯重構了一遍,非常受用,重構時比較痛苦,但是后面再使用就非常輕松了,上面這些場景都是我真實用到的,因此在這里總結一下做個筆記。

所有代碼都在如下倉庫: github-validator











總結

以上是生活随笔為你收集整理的Hibernate Validator 总结大全的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

精品久久一二三区 | 视频在线观看入口黄最新永久免费国产 | 亚洲欧美日韩国产 | 久久久一本精品99久久精品 | 国产二区电影 | 成人a级黄色片 | 日韩成人免费在线电影 | 午夜视频在线观看一区二区 | 国产xxxxx在线观看 | 国产精品21区 | 精品久久久久久久久久国产 | 国产一区二区三区网站 | 91热爆视频 | 中文字幕日韩无 | 久久久久久久久久久高潮一区二区 | 国产精品久久久久久久久搜平片 | 国内精品久久久久影院日本资源 | 91秒拍国产福利一区 | 手机在线看片日韩 | 欧美日韩精品在线免费观看 | 免费在线观看日韩视频 | 亚洲美女视频在线观看 | 日日干视频 | 国产在线a | 久草视频在线看 | 黄色av影视 | 97视频在线免费观看 | 综合久久2023 | 久久久九九 | 欧美一区影院 | www.久久久com| 成年人黄色免费看 | 久久a国产 | 在线小视频你懂得 | 97免费 | 亚洲国内精品在线 | 伊人五月天| 亚洲精品一区二区在线观看 | 国产精品白丝av | 国产亚洲视频中文字幕视频 | 亚洲精品国久久99热 | 久久久久久久综合色一本 | www99久久| 99久久久国产精品免费观看 | 黄色毛片视频免费 | 久久tv| 精品在线观看免费 | 国产精品二区在线 | 午夜av一区二区三区 | 欧美人牲 | 伊人夜夜| 91看片淫黄大片在线播放 | 日韩高清免费在线观看 | 国内精品视频一区二区三区八戒 | 91av电影在线 | 国产精品色视频 | 国产在线观看你懂得 | 国产在线观看国语版免费 | 爱射综合 | 九九99| 日韩精品一区二区三区在线播放 | 久久免费毛片 | 99产精品成人啪免费网站 | 99精品在线直播 | 最近中文字幕久久 | 久久久久北条麻妃免费看 | 国产精品久久二区 | 亚洲一级电影 | 国产亚洲精品无 | 日韩电影中文字幕在线 | 6080yy精品一区二区三区 | 久久五月婷婷丁香 | 国内精品久久久久影院一蜜桃 | 激情黄色av | 久草在线免费色站 | 美女福利视频 | 日韩精品首页 | 韩国中文三级 | 国产精品久久久久久久久久99 | 欧美日韩综合在线 | 中文字幕在线免费观看视频 | 久久伊人爱 | 天天操天天摸天天爽 | 精品视频免费在线 | 午夜av在线 | 久久综合五月婷婷 | 最近最新中文字幕视频 | 欧美日韩在线视频一区二区 | 黄色影院在线播放 | 精品国产一区二区久久 | 视频一区二区三区视频 | 免费a v网站 | 国产精品久久久久久久久久免费看 | 在线看一区 | 在线播放一区 | 男女激情片在线观看 | 国产免费a | 麻豆免费视频观看 | 久久久国产精品成人免费 | av电影中文 | 亚洲女同ⅹxx女同tv | 在线观看成人一级片 | 久艹视频在线免费观看 | 99久久999久久久精玫瑰 | 国产一级在线观看视频 | 91中文在线观看 | 伊人久久在线观看 | 国产一区免费在线 | 天天干天天拍天天操天天拍 | 日韩电影久久久 | www久| 91在线亚洲| 正在播放日韩 | 亚洲天天草 | 婷婷六月天丁香 | 午夜久久影院 | 精品一区精品二区高清 | 久久国产影院 | av夜夜操 | 久久精品99国产国产精 | 免费日韩电影 | 在线观看完整版免费 | 在线色亚洲 | 国产成人久久精品一区二区三区 | 国内免费的中文字幕 | av噜噜噜在线播放 | 亚洲天天综合 | 日本黄色免费播放 | 国产精品视频免费在线观看 | 中文字幕视频网站 | 在线看成人av | 国产精品一区二区av | 久久综合中文字幕 | 99精品偷拍视频一区二区三区 | 亚洲香蕉视频 | 91理论片午午伦夜理片久久 | 91免费视频网站在线观看 | 国产电影一区二区三区四区 | 亚洲国产伊人 | 国产综合精品久久 | 啪啪精品 | 中文字幕色综合网 | 久久公开免费视频 | 久草视频观看 | www.天天操 | 激情综合亚洲精品 | 国产精品久久久久久久久久不蜜月 | 在线国产能看的 | 久久亚洲免费视频 | 在线观看精品 | 国产免费小视频 | 日日操天天操狠狠操 | 人人爽久久涩噜噜噜网站 | 丁香久久五月 | 国产日韩精品一区二区三区在线 | 996久久国产精品线观看 | 99在线热播| 久草视频在线播放 | 日韩中文免费视频 | 美女在线观看网站 | 国产精品免费久久久久久 | 91成人在线观看喷潮 | 国产精品久久一区二区三区, | 国产小视频你懂的在线 | 国产在线毛片 | 伊色综合久久之综合久久 | 中文字幕在线观看第三页 | 久久精品国产一区二区 | 久久99久久99精品免费看小说 | 免费视频 三区 | 成人在线免费视频观看 | 国产精品com | 久久艹久久 | 欧美激情视频一区 | 五月天中文字幕 | 日韩欧美在线影院 | 中文字幕乱码一区二区 | 美女国内精品自产拍在线播放 | 国产日韩视频在线观看 | 亚洲精品动漫久久久久 | 亚洲成人av一区二区 | 男女视频久久久 | 69久久久久久久 | 日韩在线观看的 | 国内精品小视频 | 精品视频中文字幕 | 国产不卡片| 日韩成人精品一区二区三区 | 亚洲va欧美 | 国产精品视频资源 | 91av成人| 久久久免费在线观看 | 久久久久久毛片 | 日韩高清免费电影 | 婷久久 | 久久综合九色综合欧美就去吻 | 久久涩涩网站 | 久久综合婷婷 | 国产美女视频免费观看的网站 | 精品麻豆入口免费 | 久久久久高清 | 国产高清视频色在线www | 人成在线免费视频 | 人人澡超碰碰97碰碰碰软件 | 欧美成人精品欧美一级乱黄 | 中文字幕精品一区二区精品 | 日韩www在线 | 国内精品久久久 | 激情五月看片 | 久久国产网 | 国产精品热 | 国产精品av免费 | 二区中文字幕 | 欧美综合色在线图区 | 最新av电影网站 | 日韩欧美综合精品 | 国色天香在线 | 国产精品国产亚洲精品看不卡 | 国产精品二区在线观看 | 黄网在线免费观看 | 国产1区2区3区在线 亚洲自拍偷拍色图 | 午夜精品久久久 | 国产精品videoxxxx | 久久中文欧美 | 国产精品网址在线观看 | 免费色视频 | av无限看| av免费电影在线 | 国产中文字幕三区 | 久久久黄色免费网站 | 国产美女在线精品免费观看 | 视频精品一区二区三区 | 日韩超碰在线 | 二区三区中文字幕 | 欧美黄色特级片 | 精品96久久久久久中文字幕无 | 国内精品在线一区 | 中文字幕字幕中文 | 欧美了一区在线观看 | 亚洲精品乱码 | 在线观看av国产 | 国产精久久久久久妇女av | 97电院网手机版 | 国产三级午夜理伦三级 | 狠狠色狠狠色综合系列 | 国产精品6 | 夜夜嗨av色一区二区不卡 | 日本精品久久久一区二区三区 | 天天射天天射天天射 | 国产精品免费麻豆入口 | www.色综合.com | 成人a毛片 | 中文字幕资源在线 | 国产精品一区二区吃奶在线观看 | 亚洲精品中文在线 | 视频成人永久免费视频 | av黄免费看 | 久久国产热 | 日本动漫做毛片一区二区 | 国产精品网红福利 | 91av视屏| 亚洲三级国产 | 久久久久久久久久久免费 | 人人草在线观看 | 久久久亚洲精品 | 97综合视频| 日日操操操 | 月下香电影 | 色综合久久88色综合天天6 | 国产不卡视频在线 | 久久99精品久久久久久秒播蜜臀 | 精品国产一区二区三区四 | 国产成人在线综合 | va视频在线 | 国产三级精品在线 | 色综合天天视频在线观看 | 久久久久久国产精品免费 | 欧美日韩在线观看视频 | 亚洲日本色 | 91麻豆国产| 91成人在线观看高潮 | 综合铜03 | 久草在线视频免赞 | 国产精品 中文在线 | 中文在线字幕观看电影 | 国内精品亚洲 | 午夜18视频在线观看 | 国产精品中文字幕在线播放 | 日韩精品一区二区在线 | 国产精品你懂的在线观看 | www.狠狠干 | 日韩r级电影在线观看 | 亚洲一区二区三区精品在线观看 | 久久综合干 | 最新久久免费视频 | 日韩高清av在线 | 国产精品毛片久久久久久久 | 九九久久久久久久久激情 | 久久www免费人成看片高清 | 国产免费激情久久 | 国内久久视频 | 又黄又刺激| 国产色婷婷在线 | 91九色在线 | 久草在线视频国产 | 午夜三级福利 | 欧美另类tv | 日本三级国产 | 精品视频99| 日韩精品视频第一页 | 久久情网 | 天天干天天操天天爱 | 波多野结衣久久资源 | 国产精品系列在线播放 | 久草在线手机观看 | 成人黄色免费观看 | 成人全视频免费观看在线看 | 操久在线| 久久免费试看 | 久久亚洲精品国产亚洲老地址 | 中文字幕一区在线观看视频 | 国产精品视频内 | 婷婷精品在线视频 | 99精品视频在线观看播放 | av资源中文字幕 | 91精品国产欧美一区二区成人 | 人成午夜视频 | 久久国产美女视频 | 日日摸日日爽 | 五月婷婷亚洲 | 91网站在线视频 | 国产午夜在线 | 天天干天天干天天操 | 国产黑丝一区二区三区 | 久草在线国产 | 在线观看你懂的网址 | 色综合亚洲精品激情狠狠 | 在线观看中文字幕 | 四虎影视久久久 | 成人a级黄色片 | 国产区精品区 | 色偷偷88888欧美精品久久久 | 久久理论电影网 | www五月天婷婷 | 亚洲闷骚少妇在线观看网站 | 少妇搡bbb| 日韩高清免费在线观看 | www麻豆视频 | 久久理伦片 | 国产又黄又爽又猛视频日本 | 国产精品成人免费一区久久羞羞 | 色综合久久五月 | 日韩成人av在线 | 精品久久福利 | 久久久视屏 | 麻豆视频国产 | 二区三区中文字幕 | 99re亚洲国产精品 | 日韩色av色资源 | 日韩视频在线播放 | 97在线观看免费视频 | 91av手机在线 | 久久在线免费观看视频 | 日韩有码第一页 | www.天天操 | 激情综合色播五月 | 亚洲国产精品一区二区久久,亚洲午夜 | 丁香五香天综合情 | 日韩欧美xxxx | 国产一区二区三区免费视频 | 久草在线欧美 | 日韩欧美在线影院 | 久久女教师 | 国产精品久久久久久久久久 | 五月丁香 | 日韩在线免费播放 | 国产传媒一区在线 | 毛片网在线 | 日韩网站免费观看 | 国产伦精品一区二区三区在线 | 亚洲视频免费 | 国产一级片一区二区三区 | www欧美日韩| 国产精品久久久免费看 | 国产精品一区在线播放 | 久久国产精品一区二区三区 | 99精品国产亚洲 | 中国一级片在线播放 | 亚洲视频在线看 | 色婷婷精品大在线视频 | 天天操夜夜操夜夜操 | 午夜精品一区二区三区在线观看 | 国产精品久久久久永久免费看 | 丁香激情综合 | 久久久久激情视频 | 亚洲电影久久久 | 国产精品自产拍在线观看桃花 | 国产资源网站 | 九九九九九九精品任你躁 | 国产精品久久久av久久久 | 五月天久久激情 | 国产剧情av在线播放 | 国产又粗又猛又黄又爽 | 人人爽影院 | 久久综合狠狠综合 | 日本精品午夜 | 国产精品wwwwww| 在线观看的av网站 | 午夜久久久久久久久久久 | 黄色免费网 | 在线视频一二三 | 日韩av成人在线观看 | 日韩欧美91 | 成人免费91| 麻豆传媒视频在线免费观看 | 国产在线精品一区二区 | 国产精品观看视频 | 人人爽人人舔 | 日韩免费在线网站 | 久久99精品国产91久久来源 | 免费在线观看成年人视频 | 亚洲专区中文字幕 | 久久人人精 | 激情开心网站 | 日韩高清一区在线 | 最新中文字幕在线观看视频 | 国产亚洲综合精品 | 亚洲精品www久久久久久 | 国产精品九九久久久久久久 | 深爱开心激情 | 精品久久久久久久久久 | 天天爽综合网 | 成人av动漫在线 | 久久精品国产一区二区 | 国产精品麻豆免费版 | 日韩欧美在线观看 | 一 级 黄 色 片免费看的 | 国产精品久久久久高潮 | 国产精品乱码一区二三区 | 国产一区在线观看视频 | 久久高清片 | 亚洲最大激情中文字幕 | 8090yy亚洲精品久久 | 色是在线视频 | 在线观看黄 | 亚洲精品视频在线免费 | 国内精品久久久久影院一蜜桃 | 久久精品一区二区三区四区 | 少妇性xxx| 视频一区久久 | 五月花婷婷 | 深爱激情五月网 | 亚洲成人av片在线观看 | 亚洲精品2区 | 91精品久久久久 | 亚洲,国产成人av | 黄色三级免费观看 | 日本中文字幕在线一区 | 麻豆系列在线观看 | 97人人添人澡人人爽超碰动图 | 国产成人在线观看免费 | 黄色avwww| 人人爽人人爽人人爽学生一级 | 免费国产一区二区 | 亚洲性xxxx | 美女国内精品自产拍在线播放 | 国产精品ⅴa有声小说 | 色干综合| 午夜久久久精品 | 一级一片免费观看 | 欧美精品久久久久性色 | 99r国产精品 | 亚洲精品乱码久久久久 | 色综合久久久久网 | 美女视频黄频 | 一级黄网 | 亚洲精品www. | 黄色毛片视频免费 | 99热超碰在线 | 中文字幕中文字幕在线中文字幕三区 | 欧美日韩中文字幕在线视频 | 久久视频在线观看中文字幕 | 国产视频 亚洲视频 | 97日日碰人人模人人澡分享吧 | 九九九免费视频 | 婷婷精品国产欧美精品亚洲人人爽 | 91亚·色 | 国产中年夫妇高潮精品视频 | 精品久久久久久久久久久久久 | 免费日韩av电影 | 综合激情 | 国产小视频在线看 | 中文字幕网站 | 免费a级毛片在线看 | 国产精品一区二区在线观看 | 久久久久免费电影 | 中文字幕视频观看 | av不卡免费在线观看 | 涩涩爱夜夜爱 | 国产精品久久久久久久久久久杏吧 | 精品在线99| 91福利试看| 国产精品久久99综合免费观看尤物 | 亚洲区另类春色综合小说校园片 | 最近中文字幕免费观看 | 色婷婷狠狠五月综合天色拍 | 久久狠狠一本精品综合网 | 手机成人在线电影 | 激情六月婷婷久久 | 在线观看视频亚洲 | 九九精品视频在线观看 | 五月开心网 | 少妇高潮冒白浆 | 黄色国产高清 | 欧美一级免费在线 | 亚洲www天堂com | 国产在线专区 | 欧美精品免费一区二区 | 精品一区二区6 | 国产精品久久视频 | 久久久久久看片 | 日日弄天天弄美女bbbb | 国产永久网站 | 久久九九久久 | 97久久久免费福利网址 | 色干干| 国偷自产中文字幕亚洲手机在线 | 国产精品女人久久久 | 97在线视频观看 | 九色福利视频 | 国产91精品在线播放 | 亚洲理论视频 | a午夜在线 | 免费h视频 | 在线a视频免费观看 | 欧美一级艳片视频免费观看 | 久久久精品二区 | 天天爽夜夜爽精品视频婷婷 | 高清国产午夜精品久久久久久 | 日日爽夜夜操 | 97av在线视频免费播放 | 激情 亚洲 | 亚洲欧美国产精品va在线观看 | 国产视频网站在线观看 | 久久精品成人欧美大片古装 | 天天操操 | 久久久www成人免费精品 | 美女视频黄,久久 | 久久综合九色综合久久久精品综合 | 91精品国产欧美一区二区成人 | 久久精品a | 国产片免费在线观看视频 | 精品一区三区 | 亚洲资源| 久久99国产精品免费 | 免费视频国产 | 99爱视频| 手机成人在线 | 人人精品久久 | 亚洲精品在线免费播放 | 久久久人人人 | 91福利视频久久久久 | 国产成人综合在线观看 | 国产精品 日韩 欧美 | 亚洲天堂va | 免费在线播放av电影 | 操久久免费视频 | 国产一级电影在线 | 久草视频在| 精品1区二区 | 日韩av免费观看网站 | 久久69精品久久久久久久电影好 | 欧美成天堂网地址 | av片子在线观看 | 夜夜操网 | 一区中文字幕电影 | 亚洲永久精品在线观看 | 中国黄色一级大片 | 亚洲aⅴ久久精品 | 久久久免费少妇 | 久草视频免费在线播放 | 99综合电影在线视频 | 91九色在线观看 | 午夜视频导航 | 特级毛片爽www免费版 | 久久久久久久亚洲精品 | 免费在线观看av | www.99av| 免费视频二区 | 91精品国产成人www | 国产在线一卡 | 一区二区精品视频 | 玖玖视频在线 | 国产精品麻豆果冻传媒在线播放 | 国产精品免费看久久久8精臀av | 五月婷婷综 | 精品女同一区二区三区在线观看 | 人人爽人人做 | 久久视频这里有久久精品视频11 | 免费日韩av片 | 中文字幕第一页在线 | 久久精品99国产精品 | 色婷婷婷 | 日日夜夜中文字幕 | 国内精品免费久久影院 | 99久久99久久综合 | 国产精品不卡视频 | 一级免费观看 | 日韩在线视频精品 | 婷婷激情小说网 | 综合久久五月天 | 国产福利网站 | 99精品在线免费在线观看 | 亚洲成av人片在线观看 | 99久久精品无免国产免费 | 射射射av | 午夜精品福利一区二区三区蜜桃 | 久草网免费 | 亚洲专区免费观看 | 亚洲日本va午夜在线电影 | av中文字幕电影 | 成年人免费av网站 | 日韩免费视频在线观看 | 又长又大又黑又粗欧美 | 亚洲91中文字幕无线码三区 | 最新久久免费视频 | 91在线蜜桃臀 | 91成人在线免费观看 | 91免费在线视频 | 日韩欧美精品在线视频 | 久久久亚洲国产精品麻豆综合天堂 | 日韩在线观看高清 | 91中文字幕一区 | bayu135国产精品视频 | 91c网站色版视频 | 亚洲精品免费看 | 91看片在线免费观看 | 国内精品久久久久久久久 | 国产美女视频网站 | 国产国产人免费人成免费视频 | 中文字幕日韩一区二区三区不卡 | 欧美a在线免费观看 | 久久久九色精品国产一区二区三区 | 99热国产在线 | 亚洲aⅴ一区二区三区 | 亚洲国产精品一区二区久久,亚洲午夜 | 99热 精品在线 | 开心丁香婷婷深爱五月 | www日日夜夜 | 一区二区三区四区在线免费观看 | 日韩精品视频一二三 | 亚洲人成人99网站 | 天天操月月操 | 99久久久国产精品美女 | 在线视频一区观看 | 五月天综合网 | 黄色三几片| 玖玖视频网 | 久久男女视频 | 亚洲精品网址在线观看 | av黄色在线播放 | 亚洲精品乱码久久久久久蜜桃91 | 国语精品免费视频 | 欧美天天射 | .精品久久久麻豆国产精品 亚洲va欧美 | 国产视频在线观看一区 | 日b视频在线观看网址 | 成年人电影免费看 | 波多野结衣在线视频免费观看 | 国产在线播放不卡 | 91黄色免费网站 | 中文字幕国产 | 91精品久久久久久久91蜜桃 | 午夜视频一区二区三区 | 色综合久久久久久中文网 | 婷婷性综合| 一区二区三区手机在线观看 | 中文在线www | 欧美天堂久久 | 国产精品va在线观看入 | 欧美日韩在线免费观看 | 色资源中文字幕 | 国产手机精品视频 | 一区二区三区在线观看免费 | 成人黄色小视频 | 亚洲国内精品在线 | www.888.av| a级黄色片视频 | 国产精品久久久久久久久久久久久 | 亚洲黄色小说网 | 色多多污污在线观看 | 久久久久久久看片 | 高清av网| 日韩在线精品 | 国产成人精品三级 | 97日日碰人人模人人澡分享吧 | 99热精品久久 | 国产高清免费av | 久久99精品久久只有精品 | 深爱激情婷婷网 | 中文字幕日韩电影 | av在线播放观看 | 一二三久久久 | 91九色porny蝌蚪主页 | 国产高清在线不卡 | 97人人精品 | 99人久久精品视频最新地址 | 久影院| 91丨九色丨91啦蝌蚪老版 | 久艹视频在线观看 | 99热最新地址 | 国产精品一区二区久久精品爱微奶 | 欧美久久精品 | 日韩久久久久久久久久久久 | 精品久久久久久久久久久久久久久久 | 亚州精品在线视频 | 国产精品大片在线观看 | 成人免费亚洲 | 香蕉网站在线观看 | 久久九九影院 | 国产在线观看免费观看 | 日韩av影视在线观看 | 亚洲一区二区三区精品在线观看 | 成人污视频在线观看 | 欧美日韩中文字幕视频 | 91久久精品一区二区二区 | 欧美成人精品在线 | 激情欧美一区二区三区 | 黄色毛片观看 | 欧美精品亚洲精品 | 国产精品久久99综合免费观看尤物 | 狠狠躁夜夜躁人人爽视频 | 亚洲免费av在线播放 | 91人人干| 亚洲一区二区精品在线 | 亚洲开心激情 | 日日夜夜综合 | 国产精品免费观看在线 | 日日操夜夜操狠狠操 | 国产视频一区在线免费观看 | 蜜臀aⅴ精品一区二区三区 久久视屏网 | 黄色片毛片 | 国产流白浆高潮在线观看 | 在线播放国产一区二区三区 | 天天色视频| 天天天天天操 | a级一a一级在线观看 | av丝袜制服 | 精品国产乱码久久久久 | 午夜视频二区 | 国产免费小视频 | 天天操天天爽天天干 | 激情影音 | 99精品在线视频播放 | 国产精品福利小视频 | 国产99久久久国产 | 久久国产精品免费一区 | 91丨九色丨蝌蚪丰满 | 国产精品电影一区 | 国产免费久久久久 | 色在线视频网 | 四虎影视国产精品免费久久 | 美女黄色网在线播放 | 91av中文| 99视频免费在线观看 | 亚洲国产精品传媒在线观看 | 久精品视频在线 | 91视频免费看网站 | 国产一区二区三区在线 | 国际精品久久 | 中文字幕中文字幕中文字幕 | 婷婷六月激情 | 日韩动态视频 | 欧美一二三专区 | 色欲综合视频天天天 | а中文在线天堂 | 日韩中文字幕在线观看 | 日韩av免费一区二区 | 欧美精品九九99久久 | 黄色一区三区 | 在线观看成人小视频 | 久久综合九色综合网站 | 欧美三级高清 | 夜夜爽88888免费视频4848 | 在线免费试看 | 国产成人精品av在线观 | 免费在线观看一级片 | 国产a级免费 | 日本婷婷色| 麻豆视频在线免费观看 | 2018亚洲男人天堂 | 婷婷六月天天 | 91视频电影 | 免费看的国产视频网站 | 中文字幕影片免费在线观看 | 欧美日韩国产精品一区二区亚洲 | 久久99国产精品视频 | 亚洲成a人片在线观看中文 中文字幕在线视频第一页 狠狠色丁香婷婷综合 | 日日综合网 | 99福利片 | 天天摸夜夜添 | 婷婷色综合 | 国产一区二区久久久 | 右手影院亚洲欧美 | 国产成人免费精品 | 亚洲a成人v | 最新日本中文字幕 | 久久久久电影 | 男女激情免费网站 | 夜夜夜夜操 | 欧美极品xxxxx | 玖玖在线观看视频 | 成人a视频 | 成年人看片网站 | 婷婷av资源 | 日批在线看 | 成人黄色毛片视频 | 爱色av.com | 狠狠狠色丁香婷婷综合激情 | 天堂网av在线| 久久综合久久综合久久综合 | 五月天天天操 | 久久免费久久 | 成人在线播放网站 | 国产经典三级 | 国产在线精品国自产拍影院 | 久久99热久久99精品 | 日本不卡一区二区 | 国产69精品久久久久久久久久 | 青青网视频 | 欧美激情精品 | 97免费视频在线播放 | 四虎永久免费网站 | 久久精品国产亚洲精品2020 | 日韩三级免费观看 | 天天色天天色天天色 | 欧美激情va永久在线播放 | 国产精品视频你懂的 | 激情婷婷色| 欧美热久久 | 五月婷婷中文网 | 97视频总站 | 91在线精品秘密一区二区 | 天天操天天操天天干 | 国产精品 国产精品 | 日韩电影一区二区在线 | 成人午夜性影院 | 韩国一区二区av | 日本中文在线观看 | 九色在线 | 久久区二区 | 在线视频亚洲 | 成人精品一区二区三区中文字幕 | 国产成人精品亚洲日本在线观看 | 国产成人一区二区三区影院在线 | 久久99久久99精品免费看小说 | 欧美日韩有码 | 99精品网站 | 日韩免费观看高清 | 中文字幕av在线播放 | 在线观看亚洲电影 | 99久久爱 | 91在线看 | 欧美日韩中文另类 | 992tv在线观看 | 久久久资源 | 青青河边草免费观看完整版高清 | 国产一级视频免费看 | 成人毛片一区二区三区 | 免费的黄色av | 精品视频免费播放 | 色婷婷激情网 | 欧美精品生活片 | 在线视频精品 | 97色资源| 色婷婷国产精品 | 欧美电影在线观看 | av高清不卡| 免费手机黄色网址 | 久久8| 国产精品自产拍在线观看中文 | 久久婷婷色综合 | 久久久久久久久久久黄色 | 精品视频在线视频 | 久久精品艹 | av在线免费在线 | 日本少妇高清做爰视频 | 亚洲天天综合网 | 免费看久久久 | 成人在线观看你懂的 | 久久99久久精品 | 日韩在线欧美在线 | 久久福利影视 | 精品影院 | 五月天最新网址 | 日日碰狠狠添天天爽超碰97久久 | 久久黄色小说 | 免费三及片 | 国产精品免费观看久久 | 国内精品久久久久影院优 | 丁香资源影视免费观看 | 91在线播放国产 | 射射色| 蜜臀av性久久久久蜜臀av | 国产美女被啪进深处喷白浆视频 | 亚洲欧美乱综合图片区小说区 | 中文字幕日韩av | www天天干 | 96国产精品视频 | 国产97免费 | 欧美激情xxxx性bbbb | 在线观看国产v片 | 欧美一级日韩三级 | 国产精品手机看片 | 菠萝菠萝在线精品视频 | 久久影院中文字幕 | 伊人久久国产精品 | 99久久精品午夜一区二区小说 | 日韩免费视频网站 | 色偷偷97 | 色婷婷国产在线 | 婷婷六月丁 | 久久天天躁狠狠躁夜夜不卡公司 | 欧美一级特黄高清视频 | 91av精品| 免费看搞黄视频网站 | 91新人在线观看 | 香蕉视频最新网址 | 精品久久久久久久久久久久久久久久久久 | 亚洲在线黄色 | 99久热精品 | 色狠狠综合天天综合综合 | 五月天色综合 | 亚洲va综合va国产va中文 | 国产午夜精品视频 | 中文在线中文资源 | 亚洲在线高清 | 精品一区二区在线免费观看 | 亚洲欧美日本A∨在线观看 青青河边草观看完整版高清 | 一区二区欧美日韩 | 久草剧场 | 一区二区三区日韩在线观看 | 九九亚洲视频 | 九九三级毛片 | 成人精品久久 | 亚洲国产精品视频在线观看 | 国产精品福利在线观看 | 国产精品不卡av | 81精品国产乱码久久久久久 | 色先锋资源网 | av国产网站 | 中文字幕一区二区三区乱码不卡 | 中文字幕在线电影 | 亚洲天堂网在线播放 | 粉嫩av一区二区三区免费 | 国产成人av在线影院 | 99久久精品国产一区二区三区 | 国产淫a| 国产粉嫩在线 | 久久蜜臀一区二区三区av | 在线 你懂 | 98福利在线| 四虎成人网 | 久久久影院| 一区二区三区四区久久 | 久久久亚洲精品 | 精油按摩av | 日韩亚洲国产中文字幕 | 色综合天天色 | 久久综合影音 | 精品在线观看免费 | 天天爱天天射天天干天天 | 国产精品嫩草在线 | 国产理论在线 | 亚洲97在线 | 精品久久久久久久久久岛国gif | 久草视频精品 | 国产剧情久久 | 成年人黄色大片在线 | 久久99国产综合精品免费 | 黄色国产高清 | 欧美激情精品久久久久久免费 | 精品久久久久一区二区国产 | 国产精品丝袜久久久久久久不卡 | 国产精品丝袜 | 免费看网站在线 | 狠狠色噜噜狠狠狠狠2022 | 国产麻豆传媒 | 久久久91精品国产一区二区精品 | 久久成人午夜 | 久久久三级视频 | 国产午夜不卡 | 99精品视频播放 | 国产精品免费观看网站 | 亚州国产精品久久久 | 九九免费在线视频 | 中文字幕在线观看免费 | 欧美另类美少妇69xxxx |