精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Java如何優雅地實現接口數據校驗

開發 后端
本篇文章給大家分享平時開發中總結的一點小技巧!在工作中寫過Java程序的朋友都知道,目前使用Java開發服務最主流的方式就是通過Spring MVC定義一個Controller層接口,并將接口請求或返回參數分別定義在一個Java實體類中,這樣Spring MVC在接收到Http請求(POST/GET)后,就會自動將請求報文自動映射成一個Java對象。

[[356232]]

本文轉載自微信公眾號「無敵碼農」,作者無敵碼農。轉載本文請聯系無敵碼農公眾號。

本篇文章給大家分享平時開發中總結的一點小技巧!在工作中寫過Java程序的朋友都知道,目前使用Java開發服務最主流的方式就是通過Spring MVC定義一個Controller層接口,并將接口請求或返回參數分別定義在一個Java實體類中,這樣Spring MVC在接收到Http請求(POST/GET)后,就會自動將請求報文自動映射成一個Java對象。這樣的代碼通常是這樣寫的:

  1. @RestController 
  2. public class OrderController { 
  3.  
  4.     @Autowired 
  5.     private OrderService orderServiceImpl; 
  6.  
  7.     @PostMapping("/createOrder"
  8.     public CreateOrderBO validationTest(@Validated CreateOrderDTO createOrderDTO) { 
  9.         return orderServiceImpl.createOrder(createOrderDTO); 
  10.     } 

這樣的代碼相信大家并不陌生,但在后續的邏輯實現過程中卻會遇到這樣的問題:“在接收請求參數后如何實現報文對象數據值的合法性校驗?”。一些同學也可能認為這并不是什么問題,因為具體某個參數字段是否為空、值的取值是否在約定范圍、格式是否合法等等,在業務代碼中校驗就好了。例如可以在Service實現類中對報文格式進行各種if-else的數據校驗。

從功能上說冗余的if-else代碼沒啥毛病,但從代碼的優雅性來說冗長的if-else代碼會顯得非常臃腫。接下來的內容將給大家介紹一種處理此類問題的實用方法。具體將從以下幾個方面進行介紹:

  • 使用@Validated注解實現Controller接口層數據直接綁定校驗;
  • 擴展約束性注解實現數據取值范圍的校驗;
  • 更加靈活的對象數據合法性校驗工具類封裝;
  • 數據合法性校驗結果異常統一返回處理;

Controller接口層數據綁定校驗

實際上在Java開發中目前普通使用的Bean數據校驗工具是"hibernate-validator",它是一個hibernete獨立的jar包,所以使用這個jar包并不需要一定要集成Hibernete框架。該jar包主要實現并擴展了javax.validation(是一個基于JSR-303標準開發出來的Bean校驗規范)接口。

由于Spring Boot在內部默認集成了"hibernate-validator",所以使用Spring Boot構建的Java工程可以直接使用相關注解來實現Bean的數據校驗。例如我們最常編寫的Controller層接口參數對象,可以在定義Bean類時直接編寫這樣的代碼:

  1. @Data 
  2. public class CreateOrderDTO { 
  3.  
  4.     @NotNull(message = "訂單號不能為空"
  5.     private String orderId; 
  6.     @NotNull(message = "訂單金額不能為空"
  7.     @Min(value = 1, message = "訂單金額不能小于0"
  8.     private Integer amount; 
  9.     @Pattern(regexp = "^1[3|4|5|7|8][0-9]{9}$", message = "用戶手機號不合法"
  10.     private String mobileNo; 
  11.     private String orderType; 
  12.     private String status; 

如上所示代碼,我們可以使用@NotNull注解來約束該字段必須不能為空,也可以使用@Min注解來約束字段的最小取值,或者還可以通過@Pattern注解來使用正則表達式來約束字段的格式(如手機號格式)等等。

以上這些注解都是“hibernate-validator”依賴包默認提供的,更多常用的注解還有很多,例如:

利用這些約束注解,我們就可以很輕松的搞定接口數據校驗,而不需要在業務邏輯中編寫大量的if-else來進行數據合法性校驗。而定義好Bean參數對象并使用相關注解實現參數值約束后,在Controller層接口定義中只需要使用@Validated注解就可以實現在接收參數后自動進行數據綁定校驗了,具體代碼如下:

  1. @PostMapping("/createOrder"
  2. public CreateOrderBO validationTest(@Validated CreateOrderDTO createOrderDTO) { 
  3.     return orderServiceImpl.createOrder(createOrderDTO); 

如上所示,在Controller層中通過Spring提供的@Validated注解可以自動實現數據Bean的綁定校驗,如果數據異常則會統一拋出校驗異常!

約束性注解擴展

在“hibernate-validator”依賴jar包中,雖然提供了很多很方便的約束注解,但是也有不滿足某些實際需要的情況,例如我們想針對參數中的某個值約定其值的枚舉范圍,如orderType訂單類型只允許傳“pay”、“refund”兩種值,那么現有的約束注解可能就沒有特別適用的了。此外,如果對這樣的枚舉值,我們還想在約束定義中直接匹配代碼中的枚舉定義,以更好地統一接口參數與業務邏輯的枚舉定義。那么這種情況下,我們還可以自己擴展定義相應地約束注解邏輯。

接下來我們定義新的約束注解@EnumValue,來實現上面我們所說的效果,具體代碼如下:

  1. @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER}) 
  2. @Retention(RUNTIME) 
  3. @Documented 
  4. @Constraint(validatedBy = {EnumValueValidator.class}) 
  5. public @interface EnumValue { 
  6.  
  7.     //默認錯誤消息 
  8.     String message() default "必須為指定值"
  9.  
  10.     //支持string數組驗證 
  11.     String[] strValues() default {}; 
  12.  
  13.     //支持int數組驗證 
  14.     int[] intValues() default {}; 
  15.  
  16.     //支持枚舉列表驗證 
  17.     Class<?>[] enumValues() default {}; 
  18.  
  19.     //分組 
  20.     Class<?>[] groups() default {}; 
  21.  
  22.     //負載 
  23.     Class<? extends Payload>[] payload() default {}; 
  24.  
  25.     //指定多個時使用 
  26.     @Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE}) 
  27.     @Retention(RUNTIME) 
  28.     @Documented 
  29.     @interface List { 
  30.         EnumValue[] value(); 
  31.     } 
  32.  
  33.     /** 
  34.      * 校驗類邏輯定義 
  35.      */ 
  36.     class EnumValueValidator implements ConstraintValidator<EnumValue, Object> { 
  37.  
  38.         //字符串類型數組 
  39.         private String[] strValues; 
  40.         //int類型數組 
  41.         private int[] intValues; 
  42.         //枚舉類 
  43.         private Class<?>[] enumValues; 
  44.  
  45.         /** 
  46.          * 初始化方法 
  47.          * 
  48.          * @param constraintAnnotation 
  49.          */ 
  50.         @Override 
  51.         public void initialize(EnumValue constraintAnnotation) { 
  52.             strValues = constraintAnnotation.strValues(); 
  53.             intValues = constraintAnnotation.intValues(); 
  54.             enumValues = constraintAnnotation.enumValues(); 
  55.         } 
  56.  
  57.         /** 
  58.          * 校驗方法 
  59.          * 
  60.          * @param value 
  61.          * @param context 
  62.          * @return 
  63.          */ 
  64.         @SneakyThrows 
  65.         @Override 
  66.         public boolean isValid(Object value, ConstraintValidatorContext context) { 
  67.             //針對字符串數組的校驗匹配 
  68.             if (strValues != null && strValues.length > 0) { 
  69.                 if (value instanceof String) { 
  70.                     for (String s : strValues) {//判斷值類型是否為Integer類型 
  71.                         if (s.equals(value)) { 
  72.                             return true
  73.                         } 
  74.                     } 
  75.                 } 
  76.             } 
  77.             //針對整型數組的校驗匹配 
  78.             if (intValues != null && intValues.length > 0) { 
  79.                 if (value instanceof Integer) {//判斷值類型是否為Integer類型 
  80.                     for (Integer s : intValues) { 
  81.                         if (s == value) { 
  82.                             return true
  83.                         } 
  84.                     } 
  85.                 } 
  86.             } 
  87.             //針對枚舉類型的校驗匹配 
  88.             if (enumValues != null && enumValues.length > 0) { 
  89.                 for (Class<?> cl : enumValues) { 
  90.                     if (cl.isEnum()) { 
  91.                         //枚舉類驗證 
  92.                         Object[] objs = cl.getEnumConstants(); 
  93.                         //這里需要注意,定義枚舉時,枚舉值名稱統一用value表示 
  94.                         Method method = cl.getMethod("getValue"); 
  95.                         for (Object obj : objs) { 
  96.                             Object code = method.invoke(obj, null); 
  97.                             if (value.equals(code.toString())) { 
  98.                                 return true
  99.                             } 
  100.                         } 
  101.                     } 
  102.                 } 
  103.             } 
  104.             return false
  105.         } 
  106.     } 

如上所示的@EnumValue約束注解,是一個非常實用的擴展,通過該注解我們可以實現對參數取值范圍(不是大小范圍)的約束,它支持對int、string以及enum三種數據類型的約束,具體使用方式如下:

  1. /** 
  2.  * 定制化注解,支持參數值與指定類型數組列表值進行匹配(缺點是需要將枚舉值寫死在字段定義的注解中) 
  3.  */ 
  4. @EnumValue(strValues = {"pay""refund"}, message = "訂單類型錯誤"
  5. private String orderType; 
  6. /** 
  7.  * 定制化注解,實現參數值與枚舉列表的自動匹配校驗(能更好地與實際業務開發匹配) 
  8.  */ 
  9. @EnumValue(enumValues = Status.class, message = "狀態值不在指定范圍"
  10. private String status; 

如上所示代碼,該擴展注解既可以使用strValues或intValues屬性來編程列舉取值范圍,也可以直接通過enumValues來綁定枚舉定義。但是需要注意,處于通用考慮,具體枚舉定義的屬性的名稱要統一匹配為value、desc,例如Status枚舉定義如下:

  1. public enum Status { 
  2.     PROCESSING(1, "處理中"), 
  3.     SUCCESS(2, "訂單已完成"); 
  4.     Integer value; 
  5.     String desc
  6.  
  7.     Status(Integer value, String desc) { 
  8.         this.value = value; 
  9.         this.desc = desc
  10.     } 
  11.  
  12.     public Integer getValue() { 
  13.         return value; 
  14.     } 
  15.  
  16.     public String getDesc() { 
  17.         return desc
  18.     } 

通過注解擴展,就能實現更多方便的約束性注解!

更加靈活的數據校驗工具類封裝

除了上面直接在Controller層使用@Validated進行綁定數據校驗外,在有些情況,例如你的參數對象中的某個字段是一個復合對象,或者業務層的某個方法所定義的入參對象也需要進行數據合法性校驗,那么這種情況下如何實現像Controller層一樣的校驗效果呢?

需要說明在這種情況下@Validated已經無法直接使用了,因為@Validated注解發揮作用主要是Spring MVC在接收參數的過程中實現了自動數據綁定校驗,而在普通的業務方法或者復合參數對象中是沒有辦法直接綁定校驗的。這種情況下,我們可以通過定義ValidateUtils工具類來實現一樣的校驗效果,具體代碼如下:

  1. public class ValidatorUtils { 
  2.  
  3.     private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); 
  4.  
  5.     /** 
  6.      * bean整體校驗,有不合規范,拋出第1個違規異常 
  7.      */ 
  8.     public static void validate(Object obj, Class<?>... groups) { 
  9.         Set<ConstraintViolation<Object>> resultSet = validator.validate(obj, groups); 
  10.         if (resultSet.size() > 0) { 
  11.             //如果存在錯誤結果,則將其解析并進行拼湊后異常拋出 
  12.             List<String> errorMessageList = resultSet.stream().map(o -> o.getMessage()).collect(Collectors.toList()); 
  13.             StringBuilder errorMessage = new StringBuilder(); 
  14.             errorMessageList.stream().forEach(o -> errorMessage.append(o + ";")); 
  15.             throw new IllegalArgumentException(errorMessage.toString()); 
  16.         } 
  17.     } 

如上所示,我們定義了一個基于"javax.validation"接口的工具類實現,這樣就可以在非@Validated直接綁定校驗的場景中通過校驗工具類來實現對Bean對象約束注解的校驗處理,具體使用代碼如下:

  1. public boolean orderCheck(OrderCheckBO orderCheckBO) { 
  2.     //對參數對象進行數據校驗 
  3.     ValidatorUtils.validate(orderCheckBO); 
  4.     return true

而方法入參對象則還是可以繼續使用前面我們介紹的約束性注解進行約定,例如上述方法的入參對象定義如下:

  1. @Data 
  2. @Builder 
  3. public class OrderCheckBO { 
  4.  
  5.     @NotNull(message = "訂單號不能為空"
  6.     private String orderId; 
  7.     @Min(value = 1, message = "訂單金額不能小于0"
  8.     private Integer orderAmount; 
  9.     @NotNull(message = "創建人不能為空"
  10.     private String operator; 
  11.     @NotNull(message = "操作時間不能為空"
  12.     private String operatorTime; 

這樣在編程體驗上就可以整體上保持一致!

數據合法性校驗結果異常統一處理

通過前面我們所講的各種約束注解,我們實現了對Controller層接口以及業務方法參數對象的統一數據校驗。而為了保持校驗異常處理的統一處理和錯誤報文統一輸出,我們還可以定義通用的異常處理機制,來保證各類數據校驗錯誤都能以統一錯誤格式反饋給調用方。具體代碼如下:

  1. @Slf4j 
  2. @ControllerAdvice 
  3. public class GlobalExceptionHandler { 
  4.     /** 
  5.      * 統一處理參數校驗錯誤異常(非Spring接口數據綁定驗證) 
  6.      * 
  7.      * @param response 
  8.      * @param e 
  9.      * @return 
  10.      */ 
  11.     @ExceptionHandler(BindException.class) 
  12.     @ResponseBody 
  13.     public ResponseResult<?> processValidException(HttpServletResponse response, BindException e) { 
  14.         response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); 
  15.         //獲取校驗錯誤結果信息,并將信息組裝 
  16.         List<String> errorStringList = e.getBindingResult().getAllErrors() 
  17.                 .stream().map(ObjectError::getDefaultMessage).collect(Collectors.toList()); 
  18.         String errorMessage = String.join("; ", errorStringList); 
  19.         response.setContentType("application/json;charset=UTF-8"); 
  20.         log.error(e.toString() + "_" + e.getMessage(), e); 
  21.         return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9998.getCode(), 
  22.                 errorMessage); 
  23.     } 
  24.  
  25.     /** 
  26.      * 統一處理參數校驗錯誤異常 
  27.      * 
  28.      * @param response 
  29.      * @param e 
  30.      * @return 
  31.      */ 
  32.     @ExceptionHandler(IllegalArgumentException.class) 
  33.     @ResponseBody 
  34.     public ResponseResult<?> processValidException(HttpServletResponse response, IllegalArgumentException e) { 
  35.         response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); 
  36.         String errorMessage = String.join("; ", e.getMessage()); 
  37.         response.setContentType("application/json;charset=UTF-8"); 
  38.         log.error(e.toString() + "_" + e.getMessage(), e); 
  39.         return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9998.getCode(), 
  40.                 errorMessage); 
  41.     } 
  42.  
  43.     ... 

如上所示,我們定義了針對前面兩種數據校驗方式的統一異常處理機制,這樣數據校驗的錯誤信息就能通過統一的報文格式反饋給調用端,從而實現接口數據報文的統一返回!

其中通用的接口參數對象ResponseResult的代碼定義如下:

  1. @Data 
  2. @Builder 
  3. @NoArgsConstructor 
  4. @AllArgsConstructor 
  5. @JsonPropertyOrder({"code""message""data"}) 
  6. public class ResponseResult<T> implements Serializable { 
  7.  
  8.     private static final long serialVersionUID = 1L; 
  9.  
  10.     /** 
  11.      * 返回的對象 
  12.      */ 
  13.     @JsonInclude(JsonInclude.Include.NON_NULL) 
  14.     private T data; 
  15.     /** 
  16.      * 返回的編碼 
  17.      */ 
  18.     private Integer code; 
  19.     /** 
  20.      * 返回的信息 
  21.      */ 
  22.     private String message; 
  23.  
  24.     /** 
  25.      * @param data 返回的數據 
  26.      * @param <T>  返回的數據類型 
  27.      * @return 響應結果 
  28.      */ 
  29.     public static <T> ResponseResult<T> OK(T data) { 
  30.         return packageObject(data, GlobalCodeEnum.GL_SUCC_0); 
  31.     } 
  32.  
  33.     /** 
  34.      * 自定義系統異常信息 
  35.      * 
  36.      * @param code 
  37.      * @param message 自定義消息 
  38.      * @param <T> 
  39.      * @return 
  40.      */ 
  41.     public static <T> ResponseResult<T> systemException(Integer code, String message) { 
  42.         return packageObject(null, code, message); 
  43.     } 

當然,這樣的統一報文格式也不僅僅只處理異常返回,正常的數據報文格式也可以通過該對象來進行統一封裝!

本文內容從實用的角度給大家演示了,如何在日常工作中編寫通用的數據校驗邏輯.

原文鏈接:https://mp.weixin.qq.com/s/9kKIDZYB7bR7jiC5vj6qMg

 

責任編輯:武曉燕 來源: 無敵碼農
相關推薦

2021-05-12 22:07:43

并發編排任務

2023-03-28 08:07:12

2023-06-06 08:51:06

2025-01-16 08:08:29

2021-03-24 10:20:50

Fonts前端代碼

2020-07-07 07:33:12

Java單元集成

2020-11-05 18:30:32

接口測試

2024-11-13 16:37:00

Java線程池

2017-10-20 12:59:05

數據分層數據建設數據倉庫

2020-09-25 11:30:20

Java判空代碼

2020-04-10 10:22:12

Java判空編程語言

2020-02-05 14:05:21

Java技術數組

2024-06-05 09:17:31

Python數據清洗開發

2022-08-03 07:07:10

Spring數據封裝框架

2022-05-13 21:20:23

組件庫樣式選擇器

2021-01-18 13:17:04

鴻蒙HarmonyOSAPP

2020-03-26 11:04:00

Linux命令光標

2024-04-24 12:34:08

Spring事務編程

2021-01-28 14:53:19

PHP編碼開發

2022-05-24 06:07:48

JShack用戶代碼
點贊
收藏

51CTO技術棧公眾號

不卡一卡二卡三乱码免费网站| 五月久久久综合一区二区小说| 午夜精品一区二区三区电影天堂| 久久久久久久久久码影片| 亚洲自拍一区在线观看| 日韩电影免费网址| 欧美成人video| 日韩欧美xxxx| 性欧美ⅴideo另类hd| 99久久久国产精品| 91精品中国老女人| 中文字幕av影院| 91精品国产成人观看| 亚洲精品国产拍免费91在线| 亚洲老女人av| 9191在线播放| 久久久久久久久久久99999| 国产一区二区香蕉| 制服.丝袜.亚洲.中文.综合懂色| 999久久久精品国产| 亚洲精品国产精品国自产观看浪潮 | 女人另类性混交zo| 三级资源在线| 欧美韩国日本不卡| 黄色一区三区| 精品久久久中文字幕人妻| 久久精品麻豆| 久久久久久久久久国产精品| 蜜桃av乱码一区二区三区| 国产精品玖玖玖在线资源| 欧美久久一二区| 欧美视频第三页| av成人影院在线| 一区二区三区色| 一本一道久久a久久精品综合| 色av男人的天堂免费在线| 国产91在线看| 51成人做爰www免费看网站| 亚洲av无码不卡| 国产精品亚洲欧美| 久久久久久久久国产精品| 日韩高清dvd碟片| 欧美激情777| 一区二区三区国产视频| 大又大又粗又硬又爽少妇毛片| 99精品国产一区二区三区2021| 欧美老肥妇做.爰bbww| 日韩爱爱小视频| 欧美三级精品| 在线区一区二视频| 欧美成人免费高清视频| 亚洲黄色中文字幕| 欧美天堂在线观看| 日日碰狠狠添天天爽超碰97| 国产黄大片在线观看| 亚洲成va人在线观看| 91黄色在线看| 黄色aa久久| 性欧美大战久久久久久久久| 性高湖久久久久久久久aaaaa| 污视频在线看网站| 亚洲尤物在线视频观看| 成人在线免费观看视频网站| 日本在线视频网址| 亚洲一区在线观看视频| 日韩伦理在线免费观看| 2021中文字幕在线| 精品国产鲁一鲁一区二区张丽| 国产96在线 | 亚洲| 水蜜桃在线视频| 色婷婷av一区二区三区之一色屋| 中文字幕第36页| 精品久久国产一区| 精品噜噜噜噜久久久久久久久试看| 国产精品嫩草69影院| 国产精品x8x8一区二区| 亚洲欧洲第一视频| 亚洲色图27p| 欧美成熟视频| 538国产精品一区二区在线 | 亚洲天堂av中文字幕| 国产精品不卡| 久久久久久久久久久91| 中文在线第一页| 黄页网站大全一区二区| 国产传媒一区| 久久综合九色综合久| 国产精品久久久久久久岛一牛影视| 91精品一区二区三区四区| www.九色在线| 欧美日韩一区二区三区不卡| 国产精品19p| 日韩a级大片| 中文字幕精品一区久久久久| 久青草视频在线观看| 亚欧美中日韩视频| 国产专区欧美专区| 婷婷开心激情网| 国产精品久久久一本精品| 免费看毛片的网址| 台湾成人免费视频| 精品少妇一区二区三区免费观看| 97人妻精品一区二区免费| 小处雏高清一区二区三区| 韩日精品中文字幕| 中文字幕永久免费视频| 99r国产精品| 91手机视频在线| 免费日韩电影| 欧美成人video| 91n在线视频| 久久久久国产精品一区二区| 666精品在线| 1769视频在线播放免费观看| 午夜精品久久久久久| 国产精品久久久久久久av福利| 亚洲丁香日韩| 欧美精品18videos性欧美| 一级黄色片视频| 久久精品夜夜夜夜久久| 国产日韩av网站| 国产在线一区不卡| 中文字幕亚洲欧美一区二区三区 | av在线免费网址| 欧美三级日韩三级| 波多野结衣片子| 亚洲综合精品四区| 国产视频精品网| 欧美人与性动交α欧美精品图片| 欧美日本国产一区| 久久久久久久毛片| 老**午夜毛片一区二区三区| 黄色一区三区| 欧美男人天堂| 亚洲精品久久久久中文字幕欢迎你 | 亚洲精品写真福利| 亚洲图色中文字幕| 日韩中文字幕高清在线观看| 国产成人一区二区| 你懂的在线观看| 欧美性猛交xxx| 日韩网站在线播放| 亚洲一区二区成人| 久久久7777| 91精品论坛| 亚洲欧美激情四射在线日| yjizz国产| 91理论电影在线观看| www黄色av| 亚洲人成伊人成综合图片| 欧洲一区二区视频| 国产三级在线| 欧美日韩免费视频| 日本 欧美 国产| 国产精选一区二区三区| 狠狠噜天天噜日日噜| 一区二区三区欧洲区| 欧美激情一区二区三区高清视频| 高清乱码毛片入口| 亚洲成a人片综合在线| 亚洲啪av永久无码精品放毛片 | 国产精品成人免费| 97超碰人人爽| 欧美精品99| 国产精品日韩一区二区三区| а√在线天堂官网| 亚洲精品中文字幕有码专区| 97人妻一区二区精品视频| 国产精品网站在线观看| 91福利免费观看| 欧美日韩在线大尺度| 精品日韩电影| 麻豆精品蜜桃| 久久国产精品久久精品| 欧美 日韩 中文字幕| 日本久久一区二区三区| 又色又爽的视频| 国产盗摄精品一区二区三区在线| 隔壁人妻偷人bd中字| 日韩精品a在线观看91| 国产精品96久久久久久| 麻豆传媒在线完整视频| 亚洲а∨天堂久久精品9966| 天堂网视频在线| 亚洲欧洲精品天堂一级| 你懂的在线观看网站| 日韩av中文字幕一区二区三区| 永久域名在线精品| 另类在线视频| 国产日韩在线观看av| 欧美1234区| 国产亚洲精品久久| www.狠狠干| 日本高清不卡一区| 国模无码国产精品视频| 91女人视频在线观看| 国产亚洲视频一区| 国产精品久久国产愉拍| 一级一片免费播放| 亚洲精品进入| 97se亚洲综合| 国产第一精品| 欧美一区二区视频97| 91在线中文| 国产亚洲精品久久久久动| 午夜免费福利视频| 欧美艳星brazzers| 日韩成人高清视频| 亚洲男帅同性gay1069| 日本黄色网址大全| 成人一区二区视频| 在线观看日本一区二区| 噜噜噜在线观看免费视频日韩 | 黄色片在线观看网站| 久久久电影一区二区三区| 欧美极品jizzhd欧美仙踪林| 久久狠狠亚洲综合| 波多野结衣家庭教师视频| 欧美日本一区二区视频在线观看| 视频一区二区综合| 日韩超碰人人爽人人做人人添| 91久久偷偷做嫩草影院| 四虎视频在线精品免费网址| 日韩美女在线观看| а√在线天堂官网| 久久久久久中文| 成人福利网站| 日韩视频在线观看免费| 福利视频在线导航| 亚洲欧美日本精品| 亚洲欧美自偷自拍| 亚洲国产天堂网精品网站| 99久久国产免费| 7777精品伊人久久久大香线蕉经典版下载| 久久国产视频一区| 狠狠色狠狠色综合日日五| 国产乡下妇女做爰视频| 亚洲影视资源网| 欧美成人精品一区二区免费看片| 亚洲视频免费在线观看| 911国产在线| 成人欧美一区二区三区视频网页| 欧美一区二区三区粗大| 欧美国产日本视频| 永久免费毛片在线观看| 欧美激情一区二区三区全黄| 男人的天堂av网| 国产精品看片你懂得| 国产又粗又长又硬| 自拍偷自拍亚洲精品播放| xxxx日本少妇| 亚洲综合久久久久| 国产无码精品在线播放| 亚洲成av人综合在线观看| 国产在线精品观看| 欧美日韩国产精品一区二区不卡中文| 国产无码精品一区二区| 欧美日韩中文字幕| 久久人人爽人人爽人人片av免费| 欧美性受xxxx| 国产又粗又猛又爽又黄的视频一| 777午夜精品视频在线播放| 国产视频在线观看免费| 精品精品欲导航| 五月婷婷深深爱| 亚洲一区av在线播放| 日本中文字幕在线观看| 欧美成人激情视频免费观看| 尤物视频在线看| 69视频在线播放| 99欧美精品| 91影院未满十八岁禁止入内| 国产欧美三级电影| 日韩精品一区二区三区外面| 欧美丰满日韩| 男人添女人下面高潮视频| 狂野欧美一区| 18深夜在线观看免费视频| 成人免费视频视频在线观看免费| 欧美老熟妇乱大交xxxxx| 中文字幕一区av| 亚洲黄色三级视频| 欧美三级电影在线观看| www男人的天堂| 亚洲日本中文字幕| av软件在线观看| 欧美一级电影在线| 996久久国产精品线观看| 国产欧美日韩一区二区三区| re久久精品视频| 99色这里只有精品| 久久精品99国产精品| 日本一区二区免费视频| 国产精品视频一二三区| 久久久久亚洲av无码专区| 在线看国产一区二区| 亚洲av永久无码国产精品久久| 亚洲人成电影网站色xx| 欧美bbbxxxxx| 国产精品嫩草影院久久久| 91综合精品国产丝袜长腿久久| 婷婷久久伊人| 亚洲资源av| 伊人影院在线观看视频| 欧美高清在线视频| 日韩成人免费在线视频| 91精品国产综合久久精品性色| 韩国三级在线观看久| 韩剧1988免费观看全集| 美女精品视频在线| 日本不卡在线播放| 亚洲激情网站| 精品国产鲁一鲁一区二区三区| 国产亚洲一区二区三区四区| 久久精品久久精品久久| 91超碰这里只有精品国产| xxxxx日韩| 欧洲成人午夜免费大片| 粉嫩久久久久久久极品| 日韩专区第三页| 国产在线精品免费| 天堂av网手机版| 欧美在线|欧美| 嫩草研究院在线观看| 91国语精品自产拍在线观看性色| 欧美中文高清| 黄色录像特级片| 国内精品自线一区二区三区视频| 欧美在线视频免费| av电影院在线看| 亚洲国内精品在线| 黄网站在线免费看| 国产精品无码专区在线观看| 国产精品最新| 亚洲自偷自拍熟女另类| 成人动漫av在线| 国产一级片免费| 精品成人在线观看| 欧洲黄色一区| 国产精品久久精品国产 | 一级片免费观看视频| 国产一区二区日韩精品欧美精品| 人在线成免费视频| 久久精品国产综合精品| av成人天堂| 蜜桃精品成人影片| 色一情一乱一乱一91av| 美国一级片在线免费观看视频 | 亚洲黄色三级视频| 日韩精品极品毛片系列视频| 麻豆mv在线看| 欧美高清视频一区二区三区在线观看| 亚洲欧美春色| 波多野结衣一二三四区| 欧美三级日韩三级国产三级| 久久亚洲天堂| av一区观看| 亚洲一区二区三区四区五区午夜| 国内精品久久99人妻无码| 一道本成人在线| 1pondo在线播放免费| 成人黄色av网| 亚洲午夜久久久久久尤物| 国产精品入口麻豆| 色琪琪一区二区三区亚洲区| 成人在线观看免费| 成人做爰www免费看视频网站| 自产国语精品视频| 精品一区二区视频在线观看| 色中色一区二区| 在线看的av网站| 成人黄动漫网站免费| 国产日韩欧美| 刘亦菲国产毛片bd| 日韩欧美国产高清| 麻豆国产在线| 五月天亚洲综合| 国产aⅴ综合色| 福利网址在线观看| 久久久精品网站| 麻豆精品99| 亚洲电影免费观看| 亚洲AV无码乱码国产精品牛牛| 久久久久久久久久久成人| 色狼人综合干| 成人综合久久网| 午夜一区二区三区在线观看| 电影在线一区| 国产成人精品自拍| 日本不卡免费在线视频| 久久免费黄色网址| 亚洲欧美日韩国产成人| 国产精品久久久久久久久久久久久久久| 精品国产av无码一区二区三区| 国产喷白浆一区二区三区| www日本高清视频| 国产精品美女久久久久av超清| 午夜欧美精品| 国产三级短视频| 亚洲大胆人体在线|