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

SpringMVC 源碼分析之 FrameworkServlet

開發 架構
很多小伙伴都知道 SpringMVC 的核心是 DispatcherServlet,而 DispatcherServlet 的父類就是 FrameworkServlet,因此我們先來看看 FrameworkServlet,這有助于我們理解 DispatcherServlet。

[[389076]]

前面和小伙伴們聊了 SpringMVC 的初始化流程,相信大家對于 SpringMVC 的初始化過程都有一個基本認知了,今天我們就來看看當一個請求到達后,它的執行流程是什么樣的?當然這個流程比較長,松哥這里可能會分兩篇文章來和大家分享。

很多小伙伴都知道 SpringMVC 的核心是 DispatcherServlet,而 DispatcherServlet 的父類就是 FrameworkServlet,因此我們先來看看 FrameworkServlet,這有助于我們理解 DispatcherServlet。

1.FrameworkServlet

FrameworkServlet 繼承自 HttpServletBean,而 HttpServletBean 繼承自 HttpServlet,HttpServlet 就是 JavaEE 里邊的東西了,這里我們不做討論,從 HttpServletBean 開始就是框架的東西了,但是 HttpServletBean 比較特殊,它的特殊在于它沒有進行任何的請求處理,只是參與了一些初始化的操作,這些比較簡單,而且我們在上篇文章中也已經分析過了,所以這里我們對 HttpServletBean 不做分析,就直接從它的子類 FrameworkServlet 開始看起。

和所有的 Servlet 一樣,FrameworkServlet 對請求的處理也是從 service 方法開始,我們先來看看該方法 FrameworkServlet#service:

  1. @Override 
  2. protected void service(HttpServletRequest request, HttpServletResponse response) 
  3.   throws ServletException, IOException { 
  4.  HttpMethod httpMethod = HttpMethod.resolve(request.getMethod()); 
  5.  if (httpMethod == HttpMethod.PATCH || httpMethod == null) { 
  6.   processRequest(request, response); 
  7.  } 
  8.  else { 
  9.   super.service(request, response); 
  10.  } 

可以看到,在該方法中,首先獲取到當前請求方法,然后對 patch 請求額外關照了下,其他類型的請求統統都是 super.service 進行處理。

然而在 HttpServlet 中并未對 doGet、doPost 等請求進行實質性處理,所以 FrameworkServlet 中還重寫了各種請求對應的方法,如 doDelete、doGet、doOptions、doPost、doPut、doTrace 等,其實就是除了 doHead 之外的其他方法都重寫了。

我們先來看看 doDelete、doGet、doPost 以及 doPut 四個方法:

  1. @Override 
  2. protected final void doGet(HttpServletRequest request, HttpServletResponse response) 
  3.   throws ServletException, IOException { 
  4.  processRequest(request, response); 
  5. @Override 
  6. protected final void doPost(HttpServletRequest request, HttpServletResponse response) 
  7.   throws ServletException, IOException { 
  8.  processRequest(request, response); 
  9. @Override 
  10. protected final void doPut(HttpServletRequest request, HttpServletResponse response) 
  11.   throws ServletException, IOException { 
  12.  processRequest(request, response); 
  13. @Override 
  14. protected final void doDelete(HttpServletRequest request, HttpServletResponse response) 
  15.   throws ServletException, IOException { 
  16.  processRequest(request, response); 

可以看到,這里又把請求交給 processRequest 去處理了,在 processRequest 方法中則會進一步調用到 doService,對不同類型的請求分類處理。

doOptions 和 doTrace 則稍微有些差異,如下:

  1. @Override 
  2. protected void doOptions(HttpServletRequest request, HttpServletResponse response) 
  3.   throws ServletException, IOException { 
  4.  if (this.dispatchOptionsRequest || CorsUtils.isPreFlightRequest(request)) { 
  5.   processRequest(request, response); 
  6.   if (response.containsHeader("Allow")) { 
  7.    return
  8.   } 
  9.  } 
  10.  super.doOptions(request, new HttpServletResponseWrapper(response) { 
  11.   @Override 
  12.   public void setHeader(String name, String value) { 
  13.    if ("Allow".equals(name)) { 
  14.     value = (StringUtils.hasLength(value) ? value + ", " : "") + HttpMethod.PATCH.name(); 
  15.    } 
  16.    super.setHeader(name, value); 
  17.   } 
  18.  }); 
  19. @Override 
  20. protected void doTrace(HttpServletRequest request, HttpServletResponse response) 
  21.   throws ServletException, IOException { 
  22.  if (this.dispatchTraceRequest) { 
  23.   processRequest(request, response); 
  24.   if ("message/http".equals(response.getContentType())) { 
  25.    return
  26.   } 
  27.  } 
  28.  super.doTrace(request, response); 

可以看到這兩個方法的處理多了一層邏輯,就是去選擇是在當前方法中處理對應的請求還是交給父類去處理,由于 dispatchOptionsRequest 和 dispatchTraceRequest 變量默認都是 false,因此默認情況下,這兩種類型的請求都是交給了父類去處理。

2.processRequest

我們再來看 processRequest,這算是 FrameworkServlet 的核心方法了:

  1. protected final void processRequest(HttpServletRequest request, HttpServletResponse response) 
  2.   throws ServletException, IOException { 
  3.  long startTime = System.currentTimeMillis(); 
  4.  Throwable failureCause = null
  5.  LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext(); 
  6.  LocaleContext localeContext = buildLocaleContext(request); 
  7.  RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes(); 
  8.  ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes); 
  9.  WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); 
  10.  asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor()); 
  11.  initContextHolders(request, localeContext, requestAttributes); 
  12.  try { 
  13.   doService(request, response); 
  14.  } 
  15.  catch (ServletException | IOException ex) { 
  16.   failureCause = ex; 
  17.   throw ex; 
  18.  } 
  19.  catch (Throwable ex) { 
  20.   failureCause = ex; 
  21.   throw new NestedServletException("Request processing failed", ex); 
  22.  } 
  23.  finally { 
  24.   resetContextHolders(request, previousLocaleContext, previousAttributes); 
  25.   if (requestAttributes != null) { 
  26.    requestAttributes.requestCompleted(); 
  27.   } 
  28.   logResult(request, response, failureCause, asyncManager); 
  29.   publishRequestHandledEvent(request, response, startTime, failureCause); 
  30.  } 

這個方法雖然比較長,但是其實它的核心就是最中間的 doService 方法,以 doService 為界,我們可以將該方法的內容分為三部分:

  1. doService 之前主要是一些準備工作,準備工作主要干了兩件事,第一件事就是從 LocaleContextHolder 和 RequestContextHolder 中分別獲取它們原來保存的 LocaleContext 和 RequestAttributes 對象存起來,然后分別調用 buildLocaleContext 和 buildRequestAttributes 方法獲取到當前請求的 LocaleContext 和 RequestAttributes 對象,再通過 initContextHolders 方法將當前請求的 LocaleContext 和 RequestAttributes 對象分別設置到 LocaleContextHolder 和 RequestContextHolder 對象中;第二件事則是獲取到異步管理器并設置攔截器。
  2. 接下來就是 doService 方法,這是一個抽象方法,具體的實現在 DispatcherServlet 中,這個松哥放到 DispatcherServlet 中再和大家分析。
  3. 第三部分就是 finally 中,這個里邊干了兩件事:第一件事就是將 LocaleContextHolder 和 RequestContextHolder 中對應的對象恢復成原來的樣子(參考第一步);第二件事就是通過 publishRequestHandledEvent 方法發布一個 ServletRequestHandledEvent 類型的消息。

經過上面的分析,大家發現,processRequest 其實主要做了兩件事,第一件事就是對 LocaleContext 和 RequestAttributes 的處理,第二件事就是發布事件。我們對這兩件事分別來研究。

2.1 LocaleContext 和 RequestAttributes

LocaleContext 和 RequestAttributes 都是接口,不同的是里邊存放的對象不同。

2.1.1 LocaleContext

LocaleContext 里邊存放著 Locale,也就是本地化信息,如果我們需要支持國際化,就會用到 Locale。

國際化的時候,如果我們需要用到 Locale 對象,第一反應就是從 HttpServletRequest 中獲取,像下面這樣:

  1. Locale locale = req.getLocale(); 

但是大家知道,HttpServletRequest 只存在于 Controller 中,如果我們想要在 Service 層獲取 HttpServletRequest,就得從 Controller 中傳參數過來,這樣就比較麻煩,特別是有的時候 Service 中相關方法都已經定義好了再去修改,就更頭大了。

所以 SpringMVC 中還給我們提供了 LocaleContextHolder,這個工具就是用來保存當前請求的 LocaleContext 的。當大家看到 LocaleContextHolder 時不知道有沒有覺得眼熟,松哥在之前的 Spring Security 系列教程中和大家聊過 SecurityContextHolder,這兩個的原理基本一致,都是基于 ThreadLocal 來保存變量,進而確保不同線程之間互不干擾,對 ThreadLocal 不熟悉的小伙伴,可以看看松哥的 Spring Security 系列,之前有詳細分析過(公號后臺回復 ss)。

有了 LocaleContextHolder 之后,我們就可以在任何地方獲取 Locale 了,例如在 Service 中我們可以通過如下方式獲取 Locale:

  1. Locale locale = LocaleContextHolder.getLocale(); 

上面這個 Locale 對象實際上就是從 LocaleContextHolder 中的 LocaleContext 里邊取出來的。

需要注意的是,SpringMVC 中還有一個 LocaleResolver 解析器,所以前面 req.getLocale() 并不總是獲取到 Locale 的值,這個松哥在以后的文章中再和小伙伴們細聊。

2.1.2 RequestAttributes

RequestAttributes 是一個接口,這個接口可以用來 get/set/remove 某一個屬性。

RequestAttributes 有諸多實現類,默認使用的是 ServletRequestAttributes,通過 ServletRequestAttributes,我們可以 getRequest、getResponse 以及 getSession。

在 ServletRequestAttributes 的具體實現中,會通過 scope 參數判斷操作 request 還是操作 session(如果小伙伴們不記得 Spring 中的作用域問題,可以公號后臺回復 spring,看看松哥錄制的免費的 Spring 入門教程,里邊有講),我們來看一下 ServletRequestAttributes#setAttribute 方法(get/remove 方法執行邏輯類似):

  1. public void setAttribute(String name, Object value, int scope) { 
  2.     if (scope == 0) { 
  3.         if (!this.isRequestActive()) { 
  4.             throw new IllegalStateException("Cannot set request attribute - request is not active anymore!"); 
  5.         } 
  6.         this.request.setAttribute(name, value); 
  7.     } else { 
  8.         HttpSession session = this.obtainSession(); 
  9.         this.sessionAttributesToUpdate.remove(name); 
  10.         session.setAttribute(name, value); 
  11.     } 

可以看到,這里會先判斷 scope,scope 為 0 就操作 request,scope 為 1 就操作 session。如果操作的是 request,則需要首先通過 isRequestActive 方法判斷當前 request 是否執行完畢,如果執行完畢,就不可以再對其進行其他操作了(當執行了 finally 代碼塊中的 requestAttributes.requestCompleted 方法后,isRequestActive 就會返回 false)。

和 LocaleContext 類似,RequestAttributes 被保存在 RequestContextHolder 中,RequestContextHolder 的原理也和 SecurityContextHolder 類似,這里不再贅述。

看了上面的講解,大家應該發現了,在 SpringMVC 中,如果我們需要在 Controller 之外的其他地方使用 request、response 以及 session,其實不用每次都從 Controller 中傳遞 request、response 以及 session 等對象,我們完全可以直接通過 RequestContextHolder 來獲取,像下面這樣:

  1. ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); 
  2. HttpServletRequest request = servletRequestAttributes.getRequest(); 
  3. HttpServletResponse response = servletRequestAttributes.getResponse(); 

是不是非常 easy!

2.2 事件發布

最后就是 processRequest 方法中的事件發布了。

在 finally 代碼塊中會調用 publishRequestHandledEvent 方法發送一個 ServletRequestHandledEvent 類型的事件,具體發送代碼如下:

  1. private void publishRequestHandledEvent(HttpServletRequest request, HttpServletResponse response, 
  2.   long startTime, @Nullable Throwable failureCause) { 
  3.  if (this.publishEvents && this.webApplicationContext != null) { 
  4.   // Whether or not we succeeded, publish an event. 
  5.   long processingTime = System.currentTimeMillis() - startTime; 
  6.   this.webApplicationContext.publishEvent( 
  7.     new ServletRequestHandledEvent(this, 
  8.       request.getRequestURI(), request.getRemoteAddr(), 
  9.       request.getMethod(), getServletConfig().getServletName(), 
  10.       WebUtils.getSessionId(request), getUsernameForRequest(request), 
  11.       processingTime, failureCause, response.getStatus())); 
  12.  } 

可以看到,事件的發送需要 publishEvents 為 true,而該變量默認就是 true。如果需要修改該變量的值,可以在 web.xml 中配置 DispatcherServlet 時,通過 init-param 節點順便配置一下該變量的值。正常情況下,這個事件總是會被發送出去,如果項目有需要,我們可以監聽該事件,如下:

  1. @Component 
  2. public class ServletRequestHandleListener implements ApplicationListener<ServletRequestHandledEvent> { 
  3.     @Override 
  4.     public void onApplicationEvent(ServletRequestHandledEvent servletRequestHandledEvent) { 
  5.         System.out.println("請求執行完畢-"+servletRequestHandledEvent.getRequestUrl()); 
  6.     } 

當一個請求執行完畢時,該事件就會被觸發。

3.小結

這篇文章主要和小伙伴們分享了 SpringMVC 中 DispatcherServlet 的父類 FrameworkServlet,FrameworkServlet 的功能其實比較簡單,主要就是在 service 方法中增加了對 PATCH 的處理,然后其他類型的請求都被歸類到 processRequest 方法中進行統一處理,processRequest 方法則又分了三部分,首先是對 LocaleContext 和 RequestAttributes 的處理,然后執行 doService,最后在 finally 代碼塊中對 LocaleContext 和 RequestAttributes 屬性進行復原,同時發布一個請求結束的事件。

本文轉載自微信公眾號「江南一點雨」,可以通過以下二維碼關注。轉載本文請聯系江南一點雨公眾號。

 

責任編輯:武曉燕 來源: 江南一點雨
相關推薦

2011-05-26 10:05:48

MongoDB

2021-07-06 09:29:38

Cobar源碼AST

2024-06-13 07:55:19

2023-02-26 08:42:10

源碼demouseEffect

2012-09-20 10:07:29

Nginx源碼分析Web服務器

2011-05-26 16:18:51

Mongodb

2021-03-26 11:00:50

SpringMVC組件接口

2020-07-28 08:54:39

內核通信Netlink

2022-01-06 07:06:52

KubernetesResourceAPI

2017-01-12 14:52:03

JVMFinalRefere源碼

2022-08-27 08:02:09

SQL函數語法

2009-07-08 13:22:30

JDK源碼分析Set

2022-05-30 07:36:54

vmstoragevmselect

2012-09-06 10:07:26

jQuery

2021-09-05 07:35:58

lifecycleAndroid組件原理

2019-09-09 06:30:06

Springboot程序員開發

2023-03-17 07:53:20

K8sAPIServerKubernetes

2022-07-06 10:37:45

SpringServlet初始化

2021-02-19 06:56:33

架構協程應用

2017-01-11 14:02:32

JVM源碼內存
點贊
收藏

51CTO技術棧公眾號

www.色日本| 久久精品国产清自在天天线| 国产成人精品电影| 香蕉视频xxxx| 成人欧美亚洲| 人人香蕉久久| av福利精品导航| 久精品免费视频| 国产福利精品一区二区三区| 色播亚洲视频在线观看| 香蕉视频免费网站| h片在线观看网站| 日韩不卡一二三区| 亚洲三级av在线| 亚洲人成色77777| 三区在线视频| 久久一区二区三区四区五区| 亚洲国语精品自产拍在线观看| av日韩在线看| 免费a级片在线观看| 欧美日韩一区二区国产| 欧美一区二区三区公司| 最新av在线免费观看| 91久久国语露脸精品国产高跟| 日韩欧美一区二区三区免费看| 欧美亚洲综合久久| 亚洲一区二区高清视频| 91 中文字幕| 亚洲一区欧美激情| 亚洲天堂2020| 亚洲色偷偷色噜噜狠狠99网| 都市激情国产精品| 久久中文娱乐网| 国产精品海角社区在线观看| 色噜噜噜噜噜噜| 99久热在线精品视频观看| 日韩一区中文字幕| 91香蕉视频在线下载| 国产一级特黄a高潮片| 国内露脸中年夫妇交换精品| 天天av天天翘天天综合网 | 亚洲欧美国产制服动漫| 大j8黑人w巨大888a片| 九一国产在线| 精品在线视频一区| 久久男人资源视频| 精品无码国产污污污免费网站 | 国产精品永久免费| 欧洲美女女同性互添| 久久视频社区| 精品日韩视频在线观看| 亚洲精品乱码久久久久久蜜桃91 | 久久免费精彩视频| 日韩啪啪网站| 欧美日韩视频不卡| 无码熟妇人妻av在线电影| 性感美女一级片| 日韩成人免费在线| 国产成人精品综合久久久| 免费av网站在线| 91精品国产自产拍在线观看蜜| 精品国精品国产尤物美女| 日本一极黄色片| 新片速递亚洲合集欧美合集| 亚洲免费三区一区二区| 欧美13一14另类| 99热这里只有精品3| 国产精品久久久久9999高清| 久久精品视频va| 可以直接看的黄色网址| 精品国产一区一区二区三亚瑟| 欧美一区二区三区色| 男人添女人荫蒂国产| jizzyou欧美16| 午夜欧美大尺度福利影院在线看| 亚洲欧洲日韩综合二区| 成人高清免费在线| 亚洲午夜三级在线| 免费看污污视频| 久草在线网址| 自拍av一区二区三区| www.亚洲成人网| 黄色网在线免费看| 国产亚洲精久久久久久| 久久精品人成| 黄色小视频免费在线观看| 另类调教123区 | 亚洲天堂日韩电影| 9.1在线观看免费| 久久精品色综合| 日韩美一区二区三区| 污视频网站观看| av一区在线| 色综合久久中文综合久久牛| 九色自拍视频在线观看| 欧美aaa免费| 亚洲男女一区二区三区| 欧美亚洲另类色图| а√天堂中文在线资源8| 91国偷自产一区二区开放时间| 熟女少妇在线视频播放| 草莓视频成人appios| 日本国产一区二区| 色哟哟在线观看视频| 久久99成人| 精品香蕉一区二区三区| 免费观看一级一片| 琪琪久久久久日韩精品| 色偷偷88888欧美精品久久久 | 亚洲av无码一区二区三区dv| 久久超碰97中文字幕| 国产精品一国产精品最新章节| av小说天堂网| 国产视频一区在线播放| 97超碰国产精品| 日韩色性视频| 欧美高清视频一二三区| 日本77777| 欧美人与牛zoz0性行为| 夜夜嗨av色一区二区不卡| 最新中文字幕av| 91欧美国产| 萌白酱国产一区二区| 免费一级片视频| 伊人久久久大香线蕉综合直播| 久久久久久国产精品美女| 日本中文字幕免费观看| 噜噜噜在线观看免费视频日韩| 日本国产精品视频| 一区二区三区在线免费观看视频| 久久99深爱久久99精品| 欧美一区观看| 麻豆tv免费在线观看| 亚洲蜜臀av乱码久久精品蜜桃| 日韩中文字幕二区| 欧美交a欧美精品喷水| 欧美放荡办公室videos4k| 日本三级片在线观看| 国产伦精一区二区三区| 久久综合九色综合久99| 久久99亚洲网美利坚合众国| 91精品国产高清一区二区三区| 国产精品一区二区亚洲| 欧美日韩综合| 91成人理论电影| 大地资源网3页在线观看| 欧美喷水一区二区| 无码国产69精品久久久久网站| 亚洲色图网站| 日本中文字幕久久看| 亚洲中文字幕一区二区| 成人激情文学综合网| 日本一区二区三不卡| 自拍视频在线看| 91精品蜜臀在线一区尤物| 国产亚洲色婷婷久久99精品91| 国产一区日韩| 欧美激情免费看| 亚洲乱码在线观看| 午夜视频一区二区三区| 最新在线黄色网址| 欧美中文字幕| 欧美理论一区二区| 欧美aaaaaaa| 日韩精品在线第一页| 日韩美一区二区| 成人中文字幕在线| 亚洲国产欧美日韩| 亚洲精品成a人ⅴ香蕉片| 久久久国产精品免费| 超碰免费在线97| 偷窥国产亚洲免费视频| 在线视频第一页| 国产一区不卡视频| 亚洲欧洲精品一区| 久久一级大片| 欧美在线观看视频| 深爱五月激情五月| 亚洲精品大片www| 日本xxxx黄色| 亚洲精品中文字幕99999| 欧美精品video| 噜噜噜噜噜在线视频| 亚洲一二三区视频在线观看| 男男一级淫片免费播放| 日韩精品亚洲专区| 成年丰满熟妇午夜免费视频| 色综合久久中文| 国产日本欧美一区二区三区| 久久经典视频| 91精品国产入口在线| 丰满少妇乱子伦精品看片| 高清在线不卡av| 日本免费黄色小视频| crdy在线观看欧美| 91成品人片a无限观看| 人妻一区二区三区| 欧美在线观看视频一区二区 | 麻豆国产在线播放| 欧美一区在线视频| 无码人妻精品一区二区三区蜜桃91 | www.超碰97.com| 日韩精品电影| 国产精品乱码一区二区三区| 国产精品亚洲d| 97精品视频在线播放| 韩国av在线免费观看| 91福利社在线观看| 国产午夜精品无码| 中文字幕在线播放不卡一区| 欧美精品久久久久久久久25p| 韩日在线一区| 国产欧美欧洲| 性国裸体高清亚洲| 久久福利网址导航| 成年人在线观看网站| 亚洲国产精品成人av| 中文字幕一区二区三区精品| 亚洲少妇屁股交4| 18深夜在线观看免费视频| 日韩国产在线一| 国内性生活视频| 欧美天堂亚洲电影院在线观看| 一区二区三区四区欧美日韩| 国产一区二区欧美| 久久99久久精品国产| 91成人噜噜噜在线播放| 97在线视频免费看| 羞羞网站在线免费观看| 日韩高清a**址| www.国产com| 性久久久久久久久| 久久久久久国产精品视频| ...中文天堂在线一区| 超碰人人人人人人人| 国产经典欧美精品| 青青青国产在线观看| 国产探花在线精品| 免费影院在线观看一区| 丝袜久久网站| 免费国产一区二区| 九九综合九九| 欧美中日韩免费视频| 亚洲三级性片| 欧美日韩一区二区三区在线观看免| 精品淫伦v久久水蜜桃| 国语精品中文字幕| 国产亚洲精品精品国产亚洲综合| 欧美成年人在线观看| 成人日批视频| 欧美日韩第一页| bl在线肉h视频大尺度| 永久免费精品影视网站| 国产主播福利在线| 最近2019中文字幕大全第二页 | 国产chinasex对白videos麻豆| 欧美一区二区视频在线观看 | 亚洲色图日韩av| 青青操在线视频| 在线观看精品自拍私拍| 黄色成人在线| 欧美国产日本在线| av资源中文在线| 秋霞av国产精品一区| 日本成人伦理电影| 国产在线观看精品一区二区三区| 亚洲综合视频| 国产高清在线一区二区| 日韩欧美精品一区二区综合视频| 国产精品美女免费| 中文字幕成在线观看| 国产成+人+综合+亚洲欧美丁香花| 日韩av免费| 91精品国产一区二区三区动漫| 超碰一区二区三区| 91精品久久久久久久久久久久久 | 先锋在线资源一区二区三区| 欧美激情电影| 日本熟妇人妻xxxx| 美日韩精品视频| www.com污| 97精品久久久久中文字幕| 手机在线免费毛片| av成人老司机| 日本在线观看网址| 亚洲成人在线观看视频| 欧美成人免费观看视频| 一色桃子久久精品亚洲| 精品一区二区三区人妻| 91福利视频久久久久| 亚洲av无码乱码在线观看性色| 亚洲人成在线观看| huan性巨大欧美| 国产精品678| 国产精品18hdxxxⅹ在线| 神马影院午夜我不卡| 极品中文字幕一区| 小泽玛利亚视频在线观看| 不卡的av电影在线观看| 国产破处视频在线观看| 亚洲一区二区黄色| 91极品身材尤物theporn| 日韩精品www| 日韩成人伦理| 国产视频999| 九九精品久久| 蜜臀av性久久久久蜜臀av| 日本欧美在线看| 欧美精品久久久久久久久25p| 成人免费视频一区二区| 天堂av免费在线| 欧美性xxxx18| 亚洲午夜在线播放| 欧美精品久久一区| 蜜桃视频在线观看网站| 97精品视频在线观看| 免费一级欧美片在线观看网站| 亚洲精品成人a8198a| 欧美亚洲三级| 中文字幕在线播放一区| 一区二区三区四区在线播放 | 午夜精品久久久久久久久久蜜桃| 成人免费观看网站| 亚洲精品午夜av福利久久蜜桃| 亚洲久久中文字幕| 国产欧美日韩激情| 久久精品日韩无码| 日本高清无吗v一区| 日中文字幕在线| 77777少妇光屁股久久一区| 97视频一区| 欧美视频在线第一页| 国产伦精品一区二区三区视频青涩| 黄色录像免费观看| 欧美日韩综合色| 性开放的欧美大片| 欧美激情欧美激情在线五月| 99国内精品久久久久| 亚洲一区影院| 九色综合国产一区二区三区| 日本欧美一区二区三区不卡视频| 欧美最新大片在线看| 精品国产99久久久久久宅男i| 最近2019中文字幕一页二页| 精品国产黄a∨片高清在线| 亚洲欧洲精品一区| 久久99精品久久久久久国产越南 | 美女精品在线| 91成年人网站| 一区二区三区免费| 老熟妇一区二区三区| 亚洲午夜性刺激影院| 外国电影一区二区| 亚洲资源视频| 国产最新精品精品你懂的| 先锋资源av在线| 中文字幕在线观看一区| 国产一区二区三区在线观看| 久久伊人免费视频| 美脚恋feet久草欧美| 99在线观看视频| 欧美高清在线| 五月天婷婷在线观看视频| 久久久另类综合| 免费人成在线观看| 亚洲精品国产欧美| 偷拍中文亚洲欧美动漫| 亚洲一区二区三区加勒比| 国内不卡的二区三区中文字幕| 黄色一级片在线免费观看| 日韩av网址在线观看| 亚洲成人av观看| 三级网在线观看| 99久久精品免费| 中文字幕+乱码+中文字幕明步| 日韩三级影视基地| 免费在线观看一区| 警花观音坐莲激情销魂小说| av在线不卡电影| 在线免费看毛片| 国产+人+亚洲| 日韩欧美高清在线播放| 性感美女一区二区三区| 色婷婷久久99综合精品jk白丝| 麻豆传媒在线免费| 久久av二区| 国产一区免费电影| www.中文字幕在线观看| 亚洲国产精品人久久电影| 朝桐光一区二区| 久久av综合网| 国产精品卡一卡二| 中文字幕一区二区三区波野结| 色综合男人天堂| 郴州新闻综合频道在线直播| 北条麻妃av高潮尖叫在线观看| 久久综合色8888| av高清一区二区| 国产精品jvid在线观看蜜臀| 一区精品久久|