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

實戰篇:解決 Swagger 和自定義參數解析器的功能沖突

開發 前端
們在上文中提到過,@RequestBody使用的參數解析器RequestResponseBodyMethodProcessor優先級高于我們自定義的參數解析器,所以為了正常使用,需要將@RequestBody 注解去掉。這就會導致swagger無法識別正確的參數類型,將請求體識別為Query Params,然后將body展開。

 

前情提要

看了上一篇文章看了同事寫的代碼,我竟然開始默默的模仿了。。。的小伙伴,應該已經對使用參數解析器來完成第三方接口的統一驗簽有了清晰的認識。

我們在上文中提到過,@RequestBody使用的參數解析器RequestResponseBodyMethodProcessor優先級高于我們自定義的參數解析器,所以為了正常使用,需要將@RequestBody 注解去掉。這就會導致swagger無法識別正確的參數類型,將請求體識別為Query Params,然后將body展開。

可以看到,所有參數都被識別為ModelAttribute類型(query標志),而我們所期待的正確格式應當是如下樣子

因為該方式可以大大提高代碼的可讀性和可復用性,所以我們要知難而上,找出問題,解決問題!

問題產生的原因

產生這個問題的根本原因就是spring mvc和swagger都對@RequestBody注解進行了單獨的判定,功能上都依賴于該注解本身。

springmvc對@RequestBody注解的依賴

就拿當前自定義的參數解析器來說,如果對請求參數加上了 @RequestBody 注解,對參數的反序列化會提前被RequestResponseBodyMethodProcessor攔截,自定義的參數解析器會失效。

具體源代碼位置:https://github.com/spring-projects/spring-framework/blob/5.2.x/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java#L111

可以看到,該參數解析器對加上@ReuqestBody注解的參數都支持解析,然后做序列化的操作。然而它在參數解析器列表中的優先級比較高,自定義的參數解析器添加到參數解析器列表之后會排在它的后面,所以如果加上@RequestBody注解,自定義的參數解析器就失效了。

因此使用自定義參數解析器一定不能使用@RequestBody注解

下圖源代碼位置:https://github.com/spring-projects/spring-framework/blob/5.2.x/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java#L129

此案例中用到的自定義參數解析器為HdxArgumentResolver

swagger對@Requestbody的依賴

經過調用棧追蹤,最終發現在兩個地方的功能會對@RequestBody注解有單獨判定!(感興趣的可以自行追蹤??)

  • 請求類型判定:也就是說POST請求類型是哪種類型,這決定了入參是否會作為Request Parameter被展開參數,也就是文中的第一張圖,整個model都被視為ModelAttribute展開了。
  • Definition屬性值填充:這確保被@RequestBody注解修飾的入參會被正常顯示,如文中第二張圖片所示。

請求類型判定

源代碼位置:https://github.com/springfox/springfox/blob/2.9.2/springfox-spring-web/src/main/java/springfox/documentation/spring/web/readers/operation/OperationParameterReader.java#L151

這里對RequestBody等常用注解進行了單獨的判定,確保這些注解修飾的入參不會被作為RequestParam展開。

Definition屬性值填充

Definition屬性中填充了入參、出參等參數類型,如果沒有相應的Model定義,則swagger信息就會是不完整的,在瀏覽器頁面中的顯示也會是不全的。填充Definition的邏輯也依賴于@RequestBody注解。

源代碼位置:https://github.com/springfox/springfox/blob/2.9.2/springfox-spring-web/src/main/java/springfox/documentation/spring/web/readers/operation/OperationModelsProvider.java#L80

可以看到,只有被RequestBody注解和RequestPart注解修飾的入參才會被接收進入Definition屬性。

綜合以上兩張圖的源代碼分析,可以看到,swagger功能依賴于@RequestBody注解,入參如果不被該注解修飾,則swagger功能就會不完整,這和在springmvc中使用獨立的參數解析器功能不得使用@RequestBody注解矛盾。

解決問題

從以上分析可以得到結論,這里的根本問題是springmvc中獨立的參數解析器功能和swagger功能上的沖突,一個要求不能加上@RequestBody注解,一個要求必須加上@RequestBody注解,所以解決方法上可以使用兩種方式

  • 從springmvc入手,想辦法提高自定義參數解析器的優先級,只要自定義的參數解析器優先級比RequestResponseBodyMethodProcessor高,則就可以在自定義的參數上加上@RequestBody注解,swagger功能自然而然就能正常了。
  • 從swagger入手,想辦法解決掉上面兩部分對@RequestBody的單獨判定,不修改springmvc相關功能也可以讓swagger功能正常。

考慮到修改springmvc功能可能會對以后的版本升級造成較大影響,這里決定利用切面修改原有的swagger對@RequestBody的兩個地方的行為,從而讓swagger功能正常。

請求類型判定的邏輯調整

首先,定義一個注解

  1. @Documented 
  2. @Retention(RetentionPolicy.RUNTIME) 
  3. @Target({ElementType.PARAMETER}) 
  4. public @interface NoSwaggerExpand { 
  5.  
  6.     /** 
  7.      * default swagger expand disable 
  8.      * @see OperationParameterReader#shouldExpand(springfox.documentation.service.ResolvedMethodParameter, com.fasterxml.classmate.ResolvedType) 
  9.      */ 
  10.     boolean expand() default false

將其加到入參上

  1. @ApiOperation(value = "demo", notes = "demo"
  2.   @PostMapping(value = "/test"
  3.   public Result<boolean> test(@HdxDecrypt @NoSwaggerExpand @ApiParam(required = true) ReqDTO reqDTO) { 
  4.       try { 
  5.           log.info(ObjectMapperFactory.getObjectMapper().writeValueAsString(reqDTO)); 
  6.       } catch (JsonProcessingException e) { 
  7.           log.error("", e); 
  8.       } 
  9.       return null
  10.   } 

然后定義切面

  1. @Slf4j 
  2. @Aspect 
  3. @Component 
  4. public class SwaggerExpandAspect { 
  5.  
  6.     private final ModelAttributeParameterExpander expander; 
  7.     private final EnumTypeDeterminer enumTypeDeterminer; 
  8.  
  9.     @Autowired 
  10.     private DocumentationPluginsManager pluginsManager; 
  11.  
  12.     @Autowired 
  13.     public SwaggerExpandAspect( 
  14.             ModelAttributeParameterExpander expander, 
  15.             EnumTypeDeterminer enumTypeDeterminer) { 
  16.         this.expander = expander; 
  17.         this.enumTypeDeterminer = enumTypeDeterminer; 
  18.     } 
  19.  
  20.     @Around("execution(* springfox.documentation.spring.web.readers.operation.OperationParameterReader.apply(..))"
  21.     public Object pointCut(ProceedingJoinPoint point) throws Throwable { 
  22.         Object[] args = point.getArgs(); 
  23.         OperationContext context = (OperationContext) args[0]; 
  24.         context.operationBuilder().parameters(context.getGlobalOperationParameters()); 
  25.         context.operationBuilder().parameters(readParameters(context)); 
  26.         return null
  27.     } 
  28.  
  29.     private List<parameter> readParameters(final OperationContext context) { 
  30.  
  31.         List<resolvedmethodparameter> methodParameters = context.getParameters(); 
  32.         List<parameter> parameters = newArrayList(); 
  33.  
  34.         for (ResolvedMethodParameter methodParameter : methodParameters) { 
  35.             ResolvedType alternate = context.alternateFor(methodParameter.getParameterType()); 
  36.             if (!shouldIgnore(methodParameter, alternate, context.getIgnorableParameterTypes())) { 
  37.  
  38.                 ParameterContext parameterContext = new ParameterContext(methodParameter, 
  39.                         new ParameterBuilder(), 
  40.                         context.getDocumentationContext(), 
  41.                         context.getGenericsNamingStrategy(), 
  42.                         context); 
  43.  
  44.                 if (shouldExpand(methodParameter, alternate)) { 
  45.                     parameters.addAll( 
  46.                             expander.expand( 
  47.                                     new ExpansionContext("", alternate, context))); 
  48.                 } else { 
  49.                     parameters.add(pluginsManager.parameter(parameterContext)); 
  50.                 } 
  51.             } 
  52.         } 
  53.         return FluentIterable.from(parameters).filter(not(hiddenParams())).toList(); 
  54.     } 
  55.  
  56.  
  57.     private Predicate<parameter> hiddenParams() { 
  58.         return new Predicate<parameter>() { 
  59.             @Override 
  60.             public boolean apply(Parameter input) { 
  61.                 return input.isHidden(); 
  62.             } 
  63.         }; 
  64.     } 
  65.  
  66.     private boolean shouldIgnore( 
  67.             final ResolvedMethodParameter parameter, 
  68.             ResolvedType resolvedParameterType, 
  69.             final Set<class> ignorableParamTypes) { 
  70.  
  71.         if (ignorableParamTypes.contains(resolvedParameterType.getErasedType())) { 
  72.             return true
  73.         } 
  74.         return FluentIterable.from(ignorableParamTypes) 
  75.                 .filter(isAnnotation()) 
  76.                 .filter(parameterIsAnnotatedWithIt(parameter)).size() > 0; 
  77.  
  78.     } 
  79.  
  80.     private Predicate<class> parameterIsAnnotatedWithIt(final ResolvedMethodParameter parameter) { 
  81.         return new Predicate<class>() { 
  82.             @Override 
  83.             public boolean apply(Class input) { 
  84.                 return parameter.hasParameterAnnotation(input); 
  85.             } 
  86.         }; 
  87.     } 
  88.  
  89.     private Predicate<class> isAnnotation() { 
  90.         return new Predicate<class>() { 
  91.             @Override 
  92.             public boolean apply(Class input) { 
  93.                 return Annotation.class.isAssignableFrom(input); 
  94.             } 
  95.         }; 
  96.     } 
  97.  
  98.     private boolean shouldExpand(final ResolvedMethodParameter parameter, ResolvedType resolvedParamType) { 
  99.         return !parameter.hasParameterAnnotation(RequestBody.class) 
  100.                 && !parameter.hasParameterAnnotation(RequestPart.class) 
  101.                 && !parameter.hasParameterAnnotation(RequestParam.class) 
  102.                 && !parameter.hasParameterAnnotation(PathVariable.class) 
  103.                 && !isBaseType(typeNameFor(resolvedParamType.getErasedType())) 
  104.                 && !enumTypeDeterminer.isEnum(resolvedParamType.getErasedType()) 
  105.                 && !isContainerType(resolvedParamType) 
  106.                 && !isMapType(resolvedParamType) 
  107.                 && !noExpandAnnotaion(parameter); 
  108.  
  109.     } 
  110.  
  111.     private boolean noExpandAnnotaion(ResolvedMethodParameter parameter) { 
  112.         log.info("開始決定是否展開問題"); 
  113.         if (!parameter.hasParameterAnnotation(NoSwaggerExpand.class)) { 
  114.             return false
  115.         } 
  116.         NoSwaggerExpand noSwaggerExpand = (NoSwaggerExpand) parameter.getAnnotations().stream().filter(item -> item instanceof NoSwaggerExpand).findAny().orElse(null); 
  117.         if (noSwaggerExpand.expand()) { 
  118.             return false
  119.         } 
  120.         return true
  121.     } 
  122.  

最重要的是這里的修改

這里加上對自定義注解修飾的入參進行了判定,使得被自定義注解修飾的入參可以被Swagger當做@RequestBody一樣處理。

Definition屬性值填充的邏輯調整

再定義一個切面

  1. @Slf4j 
  2. @Aspect 
  3. @Component 
  4. public class SwaggerDefinitionAspect { 
  5.  
  6.     private static final Logger LOG = LoggerFactory.getLogger(OperationModelsProvider.class); 
  7.     private final TypeResolver typeResolver; 
  8.  
  9.     @Autowired 
  10.     public SwaggerDefinitionAspect(TypeResolver typeResolver) { 
  11.         this.typeResolver = typeResolver; 
  12.     } 
  13.  
  14.      
  15.     @Around("execution(* springfox.documentation.spring.web.readers.operation.OperationModelsProvider.apply(..))"
  16.     public Object pointCut(ProceedingJoinPoint point) throws Throwable { 
  17.         Object[] args = point.getArgs(); 
  18.         RequestMappingContext context = (RequestMappingContext) args[0]; 
  19.         collectFromReturnType(context); 
  20.         collectParameters(context); 
  21.         collectGlobalModels(context); 
  22.         return null
  23.     } 
  24.      
  25.     private void collectGlobalModels(RequestMappingContext context) { 
  26.         for (ResolvedType each : context.getAdditionalModels()) { 
  27.             context.operationModelsBuilder().addInputParam(each); 
  28.             context.operationModelsBuilder().addReturn(each); 
  29.         } 
  30.     } 
  31.  
  32.     private void collectFromReturnType(RequestMappingContext context) { 
  33.         ResolvedType modelType = context.getReturnType(); 
  34.         modelType = context.alternateFor(modelType); 
  35.         LOG.debug("Adding return parameter of type {}", resolvedTypeSignature(modelType).or("<null>")); 
  36.         context.operationModelsBuilder().addReturn(modelType); 
  37.     } 
  38.  
  39.     private void collectParameters(RequestMappingContext context) { 
  40.  
  41.  
  42.         LOG.debug("Reading parameters models for handlerMethod |{}|", context.getName()); 
  43.  
  44.         List<resolvedmethodparameter> parameterTypes = context.getParameters(); 
  45.         for (ResolvedMethodParameter parameterType : parameterTypes) { 
  46.             if (parameterType.hasParameterAnnotation(RequestBody.class) 
  47.                     || parameterType.hasParameterAnnotation(RequestPart.class) 
  48.             || parameterType.hasParameterAnnotation(NoSwaggerExpand.class) 
  49.             ) { 
  50.                 ResolvedType modelType = context.alternateFor(parameterType.getParameterType()); 
  51.                 LOG.debug("Adding input parameter of type {}", resolvedTypeSignature(modelType).or("<null>")); 
  52.                 context.operationModelsBuilder().addInputParam(modelType); 
  53.             } 
  54.         } 
  55.         LOG.debug("Finished reading parameters models for handlerMethod |{}|", context.getName()); 
  56.     } 

在這里只改動了一處代碼,使得被自定義注解修飾的入參能夠被添加到Definition屬性中去。

做完以上兩步,即可修復springmvc獨立的參數解析器功能和swagger功能沖突的問題。

責任編輯:武曉燕 來源: 阿Q說代碼
相關推薦

2022-07-11 10:37:41

MapPart集合

2021-03-16 10:39:29

SpringBoot參數解析器

2013-01-14 11:40:50

IBMdW

2022-05-11 10:45:21

SpringMVC框架Map

2025-03-10 01:00:00

Spring參數解析器

2025-03-13 07:33:46

Spring項目開發

2024-02-22 08:06:45

JSON策略解析器

2021-03-18 10:56:59

SpringMVC參數解析器

2009-09-17 09:51:18

Eclipse JDT自定義跳轉

2016-08-31 09:19:57

2014-12-10 10:37:45

Android自定義布局

2012-07-24 15:03:19

OpenStack架構

2023-07-21 19:16:59

OpenAIChatGPT

2009-06-15 16:05:30

設計AnnotatioJava

2016-08-18 13:56:33

AndroidExecutorsubmit

2009-10-16 13:08:40

VB自定義類型參數

2009-04-16 08:29:03

IE8自定義功能瀏覽器

2017-11-08 13:31:34

分層架構代碼DDD

2022-06-24 07:08:24

OHOS自定義服務

2025-07-15 10:06:54

點贊
收藏

51CTO技術棧公眾號

日韩视频在线视频| 国产精品日韩精品| 色婷婷免费视频| 国产v综合v| 亚洲婷婷综合久久一本伊一区| 99国产在线视频| 潘金莲一级淫片aaaaaa播放| 午夜精品毛片| 亚洲男人天堂网站| xxx中文字幕| 日韩大片欧美大片| 一区二区视频在线| 欧美下载看逼逼| 国产黄色小视频在线观看| 99热这里只有成人精品国产| 综合国产在线视频| 日本一级片在线播放| 欧洲精品久久久久毛片完整版| 一区二区在线观看免费视频播放| 欧美lavv| 人妻视频一区二区三区| 免费精品视频在线| 91精品国产亚洲| 婷婷在线精品视频| 精品无人区麻豆乱码久久久| 精品国产一区二区三区四区四 | 美女撒尿一区二区三区| 国产精品成人无码专区| 色8久久久久| 日韩欧美国产视频| 中国丰满熟妇xxxx性| 婷婷视频在线| 国产亚洲va综合人人澡精品| 国产私拍一区| www.超碰在线.com| 精品亚洲成a人| 国产成人啪精品视频免费网| 国产 欧美 日韩 在线| 欧美1区2区视频| 久久精品国产69国产精品亚洲 | 精品成av人一区二区三区| 精品国产123| 真实乱偷全部视频| 久久伊人久久| 91精品国产色综合久久ai换脸| 亚州精品一二三区| 日本另类视频| 欧美视频在线一区二区三区 | www.成人网.com| 亚洲自拍偷拍色图| 国产免费的av| 狠狠色丁香婷综合久久| 国产一区二区在线免费| 在线观看国产小视频| 日韩成人免费在线| 国产精品国产三级国产专播精品人 | av在线免费观看网站| 久久久久久一二三区| 黄色99视频| 你懂的在线看| 久久精品男人天堂av| 日本一区二区三区www| 国产乱理伦片a级在线观看| 国产亚洲精品中文字幕| 日本免费高清一区二区| 国产天堂在线| 国产精品成人免费精品自在线观看| 三级三级久久三级久久18| 国产福利免费在线观看| 国产精品女人毛片| 艳母动漫在线免费观看| а√天堂资源地址在线下载| 一区二区三区精品视频| 久久亚洲国产成人精品无码区| 暖暖在线中文免费日本| 婷婷六月综合亚洲| 自拍偷拍 国产| 狂野欧美性猛交xxxx| 欧美一区永久视频免费观看| 国产免费无码一区二区| 欧洲在线一区| 一区二区三区四区精品| 成人高潮免费视频| 18成人免费观看视频| 奇米一区二区三区四区久久| 中文字幕一区二区人妻痴汉电车| 国产精品综合一区二区| 国产日韩欧美二区| 成人不用播放器| 亚洲男人都懂的| 九色在线视频观看| 色综合一区二区日本韩国亚洲| 日韩写真欧美这视频| 玖玖爱在线观看| 97视频热人人精品免费| 久久久久久久影院| 99成人精品视频| 国产成人精品一区二区三区网站观看| 精品视频第一区| 黄色一级片在线观看| 红桃av永久久久| 亚洲男人天堂av在线| 日韩成人一级| 久久九九免费视频| 四虎成人在线观看| 国产成人在线免费| 日韩欧美精品一区二区三区经典| 综合图区亚洲| 欧美性色综合网| 理论片大全免费理伦片| 久久综合电影| 国产99在线|中文| 亚洲经典一区二区三区| 亚洲国产成人一区二区三区| 菠萝蜜视频在线观看入口| 国产精品亲子伦av一区二区三区| 亚洲成av人影院在线观看| 少妇高潮在线观看| 久久精品伊人| 韩日午夜在线资源一区二区| 操你啦在线视频| 欧美日韩亚洲综合在线 | 国产精品电影一区二区三区| 5月婷婷6月丁香| 4438全国亚洲精品观看视频| 色偷偷av一区二区三区乱| 7799精品视频天天看| heyzo一本久久综合| 在线观看污视频| 欧美videos粗暴| 亚洲亚裔videos黑人hd| 欧美日韩乱国产| 北条麻妃一区二区三区| 日本丰满大乳奶| 天堂久久一区| 日韩在线视频网站| 欧美性受xxx黑人xyx性爽| 26uuu色噜噜精品一区二区| av无码久久久久久不卡网站| 精品一区二区三区中文字幕在线 | 欧美在线视频第一页| 蜜臀久久久久久久| 婷婷四月色综合| 精品国模一区二区三区| 亚洲欧美国产高清va在线播| 成人午夜视频精品一区| 不卡视频在线看| 日韩伦理在线免费观看| 99精品国产高清一区二区麻豆| 欧美成人免费全部| 国产色在线视频| 亚洲激情自拍偷拍| 色诱av手机版| 极品裸体白嫩激情啪啪国产精品| 99高清视频有精品视频| 日韩123区| 亚洲精品按摩视频| 亚洲欧美偷拍一区| 欧美国产激情一区二区三区蜜月| 男女爽爽爽视频| 天天揉久久久久亚洲精品| 成人乱色短篇合集| 美女日批视频在线观看| 亚洲第一精品夜夜躁人人爽| 日韩高清精品免费观看| 91网站黄www| 免费国产成人av| 日本不卡二三区| 成人黄在线观看| 欧美卡一卡二| 亚洲精品国产欧美| 国产一区二区视频免费| 国产精品少妇自拍| 国产精品偷伦视频免费观看了| 国内自拍视频一区二区三区| 免费一区二区三区| 久久人体av| 欧美黑人又粗大| 视频一区二区三区国产| 欧美性感一类影片在线播放| 麻豆精品国产免费| 成人高清免费观看| 欧美日韩亚洲一二三| 99久久夜色精品国产亚洲96| 91精品视频网站| 国产精品蜜臀| 国产亚洲视频中文字幕视频| 99久久精品国产色欲| 亚洲成a人在线观看| 毛片网站免费观看| 国产一区二区三区黄视频| 国产96在线 | 亚洲| 狠狠操综合网| 91免费看网站| japanese23hdxxxx日韩 | 成人免费观看在线观看| 亚洲无亚洲人成网站77777| 国产成人精品一区二区无码呦| 午夜成人在线视频| www.97视频| 99re这里只有精品视频首页| 亚洲另类第一页| 亚洲精品少妇| 中文字幕欧美日韩一区二区三区| 嗯用力啊快一点好舒服小柔久久| 国产精品aaa| 92久久精品| 久久精品亚洲一区| 国产精品一级伦理| 精品国产sm最大网站免费看 | 精品免费国产二区三区| 国产一区二区视频免费| 亚洲国产成人av| 大地资源高清在线视频观看| 26uuu精品一区二区| 韩国三级在线播放| 久久97超碰色| 国产视频在线视频| 在线综合欧美| 日韩一级片一区二区| 欧美hentaied在线观看| 欧美高清性xxxxhdvideosex| 91成人噜噜噜在线播放| 91久久夜色精品国产网站| 日韩天堂在线| 清纯唯美亚洲综合| 僵尸再翻生在线观看免费国语| 久久中文字幕在线| 91在线播放网站| 亚洲欧美在线磁力| 香蕉av一区二区三区| 精品成人免费观看| 精品黑人一区二区三区在线观看| 欧美日韩成人激情| 中文字字幕在线中文乱码| 色妞www精品视频| 亚洲精品男人的天堂| 欧美日韩国内自拍| 日韩女优在线观看| 天天综合天天综合色| 国产在线成人精品午夜| 亚洲一区中文日韩| 国产亚洲欧美精品久久久久久 | 中文字幕在线视频日韩| 九色视频成人自拍| 亚洲人成在线观| 爱爱爱免费视频在线观看| 国产亚洲一区二区在线| 国产小视频福利在线| 在线视频欧美日韩| 免费在线视频欧美| 久久夜色精品亚洲噜噜国产mv | 成人精品电影| 一区二区三区免费看| 99精品视频精品精品视频| 宅男在线精品国产免费观看| 国产精品88久久久久久| 99热这里只有精品7| 亚洲蜜桃视频| 国产精品久久久久久久久电影网| 国自产拍偷拍福利精品免费一 | 激情亚洲综合在线| 自拍一级黄色片| 大美女一区二区三区| 精品视频站长推荐| 91麻豆精品在线观看| 亚洲精品国产一区黑色丝袜| 国产欧美日韩激情| 中国一级片在线观看| 一区二区高清免费观看影视大全 | 亚洲乱码久久| 亚洲人成无码www久久久| 免费高清成人在线| 欧美视频亚洲图片| 成人国产一区二区三区精品| 双性尿奴穿贞c带憋尿| 欧美国产日韩a欧美在线观看| 成人无码精品1区2区3区免费看| 一区二区三区中文字幕精品精品 | 欧美日韩成人免费观看| 亚洲va国产天堂va久久en| 久久久成人免费视频| 欧美日韩国产高清一区二区| 亚洲成a人片77777精品| 亚洲欧美国内爽妇网| 欧美jizz18性欧美| 国模精品系列视频| 丰满少妇一区| 国产精品日韩高清| 不卡一区综合视频| 国产视频在线观看网站| 久久三级视频| a级大片免费看| 久久精品亚洲一区二区三区浴池| 日本在线一级片| 狠狠爱在线视频一区| 国产乱淫a∨片免费观看| 日韩av在线免费观看| 九色porny丨首页在线| 4438全国成人免费| 免费一级欧美片在线观看网站| 久久偷看各类wc女厕嘘嘘偷窃| 国产国产精品| 日本在线视频www| 成人黄色大片在线观看 | 在线观看成人免费视频| 午夜精品久久久久久久91蜜桃| 亚洲性视频网站| 激情国产在线| 成人蜜桃视频| 久久中文字幕av| 日本免费观看网站| av一区二区不卡| 欧美三级在线免费观看| 欧美无砖砖区免费| 深夜福利视频在线观看| 欧美激情一区二区三区久久久| 国产精品久久久久久妇女| 激情视频一区二区| 欧美日韩三级| 激情在线观看视频| 国产精品久久久久影院色老大 | 免费看特级毛片| 在线观看区一区二| 人成在线免费视频| 久久久久久久久久国产| 国产一区 二区| 综合久久国产| 人人精品人人爱| 精品人妻中文无码av在线| 欧美日韩国产专区| 香蕉国产在线视频| 97超级碰碰人国产在线观看| 日本免费精品| 日本一二三区视频在线| 蜜桃一区二区三区在线| 神马久久久久久久久久久| 色呦呦网站一区| 免费在线稳定资源站| 99伊人久久| 欧美日韩国产v| 精品在线一区| 激情亚洲成人| 日本不卡视频一区| 樱桃视频在线观看一区| 国产伦精品一区二区三区视频痴汉 | 欧美三级在线观看视频| 成人深夜在线观看| 国产精品白浆一区二小说| 亚洲视频精品在线| 天天操天天干天天爽| 高清一区二区三区四区五区| 一区二区三区欧洲区| 一本色道久久88亚洲精品综合| 久久 天天综合| 午夜精品一区二区三区视频| 91精品国产手机| 国产99re66在线视频| 精品网站在线看| 日韩国产在线一| www.99re6| 日韩午夜精品电影| 精精国产xxxx视频在线野外| 久久久久久久久久码影片| 日韩专区欧美专区| 在线视频这里只有精品| 日韩精品中文字幕在线一区| 色在线中文字幕| 亚洲图片在线观看| 国产精品18久久久久久久久 | 仙踪林久久久久久久999| 欧美熟妇另类久久久久久多毛| 午夜精品视频一区| 成人jjav| 国产精品我不卡| 日韩精品电影一区亚洲| 成人免费视频网站入口::| 日韩经典中文字幕| 欧美亚洲综合视频| 天堂…中文在线最新版在线| 国产欧美一区二区精品婷婷| 精品国产av鲁一鲁一区| 欧美最猛性xxxx| 一区二区三区午夜视频| 午夜一区二区三区免费| 91精品国产综合久久久蜜臀粉嫩| а√在线天堂官网| 在线成人性视频| 91社区在线播放| 99国产精品99| 日本韩国在线不卡| 欧美另类专区| 国产综合精品久久久久成人av| 欧美zozo另类异族| 韩国精品视频在线观看 | 97免费观看视频| www.国产精品一二区| 懂色av一区二区| 天堂av在线网站| 亚洲国产日日夜夜|