日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

詳解Tomcat中Filter的執行流程

瀏覽:378日期:2023-09-08 20:45:27
目錄前言1、Filter接口2、FilterChain接口執行流程1、創建filterChain2、執行dofilter前言

Filter是什么?Filter是servlet規范中定義的java web組件, 在所有支持java web的容器中都可以使用 它是位于前端請求到servlet之間的一系列過濾器,也可以稱之為中間件,它主要是對請求到達servlet之前做一些額外的動作:

1、權限控制2、監控3、日志管理4、等等

這里涉及到兩個接口:Filter和FilterChain

Filter和FilterChain密不可分, Filter可以實現依次調用正是因為有了FilterChain。

1、Filter接口public interface Filter { // 容器創建的時候調用, 即啟動tomcat的時候調用 public void init(FilterConfig filterConfig) throws ServletException; // 由FilterChain調用, 并且傳入FilterChain本身, 最后回調FilterChain的doFilter()方法 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException; // 容器銷毀的時候調用, 即關閉tomcat的時候調用 public void destroy(); }2、FilterChain接口public interface FilterChain { // 由Filter.doFilter()中的chain.doFilter調用 public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException;}執行流程

在前面的文章中,我們知道,tomcat啟動會執行StandardWrapperValve.java類的invoke方法:

public final void invoke(Request request, Response response){ ...... MessageBytes requestPathMB = request.getRequestPathMB(); DispatcherType dispatcherType = DispatcherType.REQUEST; if (request.getDispatcherType()==DispatcherType.ASYNC) dispatcherType = DispatcherType.ASYNC; request.setAttribute(Globals.DISPATCHER_TYPE_ATTR,dispatcherType); request.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, requestPathMB); // Create the filter chain for this request ApplicationFilterChain filterChain = ApplicationFilterFactory.createFilterChain(request, wrapper, servlet); // Call the filter chain for this request // NOTE: This also calls the servlet's service() method Container container = this.container; try { if ((servlet != null) && (filterChain != null)) { // Swallow output if needed if (context.getSwallowOutput()) {try { SystemLogHandler.startCapture(); if (request.isAsyncDispatching()) { request.getAsyncContextInternal().doInternalDispatch(); } else { filterChain.doFilter(request.getRequest(),response.getResponse()); }} finally { String log = SystemLogHandler.stopCapture(); if (log != null && log.length() > 0) { context.getLogger().info(log); }} } else {if (request.isAsyncDispatching()) { request.getAsyncContextInternal().doInternalDispatch();} else { filterChain.doFilter (request.getRequest(), response.getResponse());} } } } catch (ClientAbortException | CloseNowException e) { } ......}

上面的代碼做了如下一些動作:

1、每次請求過來都會創建一個過濾器鏈(filterChain),并把待執行的servlet對象存放到過濾器鏈中。對于每個url,對應的filter個數都是不固定的,filterchain需要保存每個請求所對應的一個filter數組,以及調用到的filter的position,以便繼續向下調用filter。2、創建了filterChain之后,就開始執行doFilter進行請求的鏈式處理。1、創建filterChain

下面我們具體來看看filterChain是怎么創建的

public static ApplicationFilterChain createFilterChain(ServletRequest request, Wrapper wrapper, Servlet servlet) { // If there is no servlet to execute, return null if (servlet == null) return null; // Create and initialize a filter chain object ApplicationFilterChain filterChain = null; if (request instanceof Request) { Request req = (Request) request; if (Globals.IS_SECURITY_ENABLED) { // Security: Do not recycle filterChain = new ApplicationFilterChain(); } else { filterChain = (ApplicationFilterChain) req.getFilterChain(); if (filterChain == null) {filterChain = new ApplicationFilterChain();req.setFilterChain(filterChain); } } } else { // Request dispatcher in use filterChain = new ApplicationFilterChain(); } filterChain.setServlet(servlet); filterChain.setServletSupportsAsync(wrapper.isAsyncSupported()); // Acquire the filter mappings for this Context StandardContext context = (StandardContext) wrapper.getParent(); FilterMap filterMaps[] = context.findFilterMaps(); // If there are no filter mappings, we are done if ((filterMaps == null) || (filterMaps.length == 0)) return filterChain; // Acquire the information we will need to match filter mappings DispatcherType dispatcher = (DispatcherType) request.getAttribute(Globals.DISPATCHER_TYPE_ATTR); String requestPath = null; Object attribute = request.getAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR); if (attribute != null){ requestPath = attribute.toString(); } String servletName = wrapper.getName(); // Add the relevant path-mapped filters to this filter chain for (FilterMap filterMap : filterMaps) { if (!matchDispatcher(filterMap, dispatcher)) { continue; } if (!matchFiltersURL(filterMap, requestPath)) continue; ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)context.findFilterConfig(filterMap.getFilterName()); if (filterConfig == null) { // FIXME - log configuration problem continue; } filterChain.addFilter(filterConfig); } // Add filters that match on servlet name second for (FilterMap filterMap : filterMaps) { if (!matchDispatcher(filterMap, dispatcher)) { continue; } if (!matchFiltersServlet(filterMap, servletName)) continue; ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)context.findFilterConfig(filterMap.getFilterName()); if (filterConfig == null) { // FIXME - log configuration problem continue; } filterChain.addFilter(filterConfig); } // Return the completed filter chain return filterChain;}

上面的代碼做了一下幾件事:

1、把要執行的servlet存放到過濾器鏈中。2、如果沒有配置過濾器則return一個空的過濾器鏈(只包含上面設置的servlet)。3、如果配置url-pattern過濾器,則把匹配的過濾器加入到過濾器鏈中4、如果配置servlet-name過濾器,則把匹配的過濾器加入到過濾器鏈中

注意: filterChain.addFilter()順序與web.xml中定義的Filter順序一致,所以過濾器的執行順序是按定義的上下順序決定的。

2、執行dofilter

創建了chain之后,就開始執行鏈式請求了,具體的邏輯如下:

private void internalDoFilter(ServletRequest request, ServletResponse response)throws IOException, ServletException { // Call the next filter if there is one if (pos < n) { ApplicationFilterConfig filterConfig = filters[pos++]; try { Filter filter = filterConfig.getFilter(); if (request.isAsyncSupported() && 'false'.equalsIgnoreCase( filterConfig.getFilterDef().getAsyncSupported())) {request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR, Boolean.FALSE); } if( Globals.IS_SECURITY_ENABLED ) {final ServletRequest req = request;final ServletResponse res = response;Principal principal = ((HttpServletRequest) req).getUserPrincipal();Object[] args = new Object[]{req, res, this};SecurityUtil.doAsPrivilege ('doFilter', filter, classType, args, principal); } else {filter.doFilter(request, response, this); } } catch (IOException | ServletException | RuntimeException e) { throw e; } catch (Throwable e) { e = ExceptionUtils.unwrapInvocationTargetException(e); ExceptionUtils.handleThrowable(e); throw new ServletException(sm.getString('filterChain.filter'), e); } return; } // We fell off the end of the chain -- call the servlet instance try { if (ApplicationDispatcher.WRAP_SAME_OBJECT) { lastServicedRequest.set(request); lastServicedResponse.set(response); } if (request.isAsyncSupported() && !servletSupportsAsync) { request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR, Boolean.FALSE); } // Use potentially wrapped request from this point if ((request instanceof HttpServletRequest) &&(response instanceof HttpServletResponse) &&Globals.IS_SECURITY_ENABLED ) { final ServletRequest req = request; final ServletResponse res = response; Principal principal =((HttpServletRequest) req).getUserPrincipal(); Object[] args = new Object[]{req, res}; SecurityUtil.doAsPrivilege('service', servlet, classTypeUsedInService, args, principal); } else { servlet.service(request, response); } } catch (IOException | ServletException | RuntimeException e) { throw e; } catch (Throwable e) { e = ExceptionUtils.unwrapInvocationTargetException(e); ExceptionUtils.handleThrowable(e); throw new ServletException(sm.getString('filterChain.servlet'), e); } finally { if (ApplicationDispatcher.WRAP_SAME_OBJECT) { lastServicedRequest.set(null); lastServicedResponse.set(null); } }}

上面的代碼邏輯如下:

1、通過position索引判斷是否執行完了所有的filter2、如果沒有,取出當前待執行的索引filter,調用其doFilter方法,在上面的接口說明中,我們看到,所有的filter類都繼承了filter接口,都實現了dofilter方法;我們也注意到,該方法接收一個filterChain對象。在這段代碼中,filter.doFilter(request, response, this);可以看到,將自身引用傳遞進去了,那么各個filter在dofilter的方法中,可以根據自身業務需要,來判斷是否需要繼續進行下面的filter鏈式執行,如果需要,就執行filterChain.doFilter方法,此時就又回到了此代碼中。如果反復3、如果執行完了所有的filter,則開始執行servlet業務模塊servlet.service(request, response);

以上就是詳解Tomcat中Filter是怎樣執行的的詳細內容,更多關于Tomcat Filter執行的資料請關注好吧啦網其它相關文章!

標簽: Tomcat
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产精品手机在线播放| 国产精品二区不卡| 国产精品分类| 在线综合视频| 香蕉久久99| 久久精品卡一| www.九色在线| 久久精品免视看国产成人| 国产精品一区二区三区www| 国模大尺度视频一区二区| 免费久久精品视频| 亚洲综合日本| 日本在线视频一区二区| 亚洲不卡av不卡一区二区| 久久久久.com| 亚洲a一区二区三区| 亚洲欧美网站在线观看| 91九色精品| 免费在线小视频| 国产精品白丝久久av网站| 丝袜美腿亚洲一区二区图片| 亚洲特色特黄| 精品国产免费人成网站| 老司机久久99久久精品播放免费| 国产一区二区三区四区二区| 久久精品欧洲| 欧美日韩99| 日本麻豆一区二区三区视频| 亚洲精品激情| 九一成人免费视频| 午夜精品网站| 91精品蜜臀一区二区三区在线| 精品国产一区二区三区2021| 精品亚洲自拍| 精品久久在线| 久久久久免费av| 久久精品欧美一区| 在线一区视频| 日本特黄久久久高潮| 欧美精品99| 天堂日韩电影| 丝袜美腿高跟呻吟高潮一区| 久久激五月天综合精品| 国产一区二区三区国产精品 | 国产精品二区不卡| 麻豆传媒一区二区三区| 超碰成人av| 热久久免费视频| 精品国产欧美日韩一区二区三区| 91看片一区| 四虎精品一区二区免费| 老司机免费视频一区二区三区| 蜜桃av在线播放| 欧美亚洲三级| 99国产精品视频免费观看一公开| 欧美一级全黄| 亚洲一区二区三区高清| 精品三区视频| 日本欧美一区| 精品一区三区| 国产日韩精品视频一区二区三区| 999国产精品| 免费视频一区二区三区在线观看 | 日韩av黄色在线| 久久久久免费| 日本不卡一区二区| 午夜精品亚洲| 久久高清免费| 精品午夜视频| 国产精品对白久久久久粗| 99国产精品私拍| 精品亚洲成人| 国产亚洲人成a在线v网站| 国产亚洲网站| 自由日本语亚洲人高潮| 欧洲一级精品| 国产成人精品三级高清久久91| 国产亚洲久久| 日韩不卡免费视频| 蜜桃av一区二区| 视频一区视频二区中文| 久久国产电影| 激情久久中文字幕| 久久夜夜操妹子| 国产成人精品三级高清久久91 | 日韩福利在线观看| 免费日韩精品中文字幕视频在线| 日本在线高清| 色婷婷精品视频| 日韩在线综合| 久久久天天操| 亚洲性图久久| 蜜桃一区二区三区在线观看| 视频在线在亚洲| 欧美日韩一区二区三区视频播放| 日本在线精品| 宅男在线一区| 免费在线观看日韩欧美| 亚洲精品一二三**| 亚洲tv在线| 免费人成精品欧美精品| 国产色综合网| 综合亚洲视频| 男女性色大片免费观看一区二区| 中文字幕亚洲影视| 人人精品人人爱| 国产精品theporn| 最新中文字幕在线播放| 国产精品专区免费| 视频一区视频二区中文字幕| 日韩动漫一区| 中文字幕色婷婷在线视频| 欧美日韩第一| 国产日韩视频在线| 欧美日韩精品一区二区视频| 久久久久久久久丰满| 老司机久久99久久精品播放免费| 久久亚洲精品伦理| 国精品产品一区| 久久成人亚洲| 免费看av不卡| 亚洲日产av中文字幕| 一本色道精品久久一区二区三区| 亚洲麻豆一区| 午夜av成人| 日本精品国产| 99视频精品全部免费在线视频| 日韩成人午夜精品| 欧美一级精品| 欧美激情91| 欧美日韩日本国产亚洲在线 | 丝袜a∨在线一区二区三区不卡| 国产精品久久久久久久久免费高清| 国产日韩欧美一区在线| 国产模特精品视频久久久久| 日韩国产一区二区三区| 欧美国产另类| 91福利精品在线观看| 欧美日一区二区在线观看| 国产精品蜜芽在线观看| 国产精品嫩模av在线| 日韩大片在线播放| 国产精品一区二区三区av麻| 久久亚洲国产| 亚洲黄色免费av| 免费日韩成人| 国产精品一线| 日韩av资源网| 蜜桃视频在线观看一区| 美女网站一区| 精品国产成人| 三上亚洲一区二区| 高清av一区| 欧美天堂视频| 国产精品一线| 麻豆精品在线观看| 日韩二区在线观看| 国产日本精品| 日韩午夜av| 美女av在线免费看| 日韩av二区| 国产在线欧美| 日韩av一二三| 99久久99久久精品国产片果冰| 中文欧美日韩| 国产精品调教视频| 午夜精品亚洲| 福利片在线一区二区| 日韩制服丝袜av| 精品日韩视频| **爰片久久毛片| 日韩精品dvd| 国产精品啊v在线| 免费日韩一区二区| 婷婷激情一区| 免费在线亚洲欧美| 日韩高清二区| 久久亚洲色图| 99免费精品| 日产午夜精品一线二线三线| 日韩二区在线观看| 亚洲精品一二| 国产一区二区三区不卡视频网站| 欧美中文字幕| 清纯唯美亚洲综合一区| 国产精品夜夜夜| 国产传媒在线| 日韩三级久久| 色综合www| 国产不卡av一区二区| 日本欧美在线看| 亚洲免费毛片| 国产欧美日韩精品一区二区三区| 国产精品主播| 久久国际精品| 午夜精品一区二区三区国产| 精品国产第一福利网站| 精品三级在线| 精品久久97| 人人精品亚洲|