上善若水
          In general the OO style is to use a lot of little objects with a lot of little methods that give us a lot of plug points for overriding and variation. To do is to be -Nietzsche, To bei is to do -Kant, Do be do be do -Sinatra
          posts - 146,comments - 147,trackbacks - 0

          概述

          ServletHandler繼承自ScopedHandler,是Jetty中用于存儲所有Filter、FilterMapping、Servlet、ServletMapping的地方,以及用于實現一次請求所對應的Filter鏈和Servlet執行流程的類。對Servlet的框架實現中,它也被認為是Handler鏈的末端,因而在它的doHandle()方法中沒有調用nextHandle()方法。

          ServletHandler的成員

          正如前面提到的,ServletHandler是一個用于管理Filter、FilterMapping、Servlet、ServletMapping的容器,因而它需要一下成員用于存儲這些它管理的實例:
              private FilterHolder[] _filters=new FilterHolder[0];
              private FilterMapping[] _filterMappings;
              
              private ServletHolder[] _servlets=new ServletHolder[0];
              private ServletMapping[] _servletMappings;
              
              private final Map<String,FilterHolder> _filterNameMap= new HashMap<String,FilterHolder>();
              private List<FilterMapping> _filterPathMappings;
              private MultiMap<String> _filterNameMappings;
              
              private final Map<String,ServletHolder> _servletNameMap=new HashMap<String,ServletHolder>();
              private PathMap _servletPathMap;
          其中FilterHolder和ServletHolder分別用于存儲Filter、Servlet實例以及其配置信息,即web.xml配置文件中的<filter>、<servlet>的配置信息(參考:Servlet、Filter、Registration的實現);而FilterMapping和ServletMapping則是FilterName到URL Pattern的mapping信息,以及ServletName到URL Pattern的mapping信息,即web.xml中的<filter-mapping>、<servlet-mapping>信息。

          其中FilterMapping包含了一個Filter適用的所有URL Pattern、Servlets、DispatcherType以及對應FilterHolder信息:
              private int _dispatches=DEFAULT;
              private String _filterName;
              private transient FilterHolder _holder;
              private String[] _pathSpecs;
              private String[] _servletNames;
          它有appliesTo()方法用于判斷傳入的path和dispatcherType是否符包含當前Filter。對于URL Pattern:*.do=>anything.do, /foo/poo/abc.do, /path/to/*=>/path/to, /path/to/abdc。

          而ServletMapping包含了ServletName和其適用的所有URL Pattern,它的URL Pattern的mapping規則和FilterMapping中的規則一樣:
              private String _servletName;
              private String[] _pathSpecs;

          在管理Filter和FilterMapping中,可以使用FilterHolder、pathSpec、DispatcherType向_filters數組中添加一個FilterHolder,并向_filterMappings數組中添加一個FilterMapping實例;而由該方法引申出來的,可以直接傳入Filter實例、Filter類實例、Filter類名,而由方法內部創建對應的FilterHolder實例;DispatcherType可以是一個EnumSet類型的DispatcherType;可以直接添加Filter或FilterMapping或兩個同時添加;也可以使用prependFilterMapping將新的FilterMapping添加到數組前。對Servlet和ServletMapping管理也是類似,使用ServletHolder和pathSpec添加_servlets數組和_servletMappings數組,并引申出Servlet可以是實例、Servlet類名、Servlet類實例,而由內部創建ServletHolder實例;也可以單獨的添加ServletHolder或ServletMapping實例。

          在ServletHandler中還有_filterNameMap和_servletNameMap實例用于存儲FilterName到FilterHolder以及ServletName到ServletHolder的映射,它在每次_filters、_servlets數組更新時都會隨著更新,并且在doStart方法中也會再更新一次;另外對Filter還有_filterPathMapping用于存儲所有FilterMapping的一個List,_filterNameMapping用于存儲ServletName到多個FilterMapping的MultiMap,對Servlet中也有_servletPathMap,包含pathSpec到ServletHolder的PathMap,他們在每次_filterMappings、_servletMappings更新時以及doStart方法中都會被更新。而在start時也會start所有的FilterHolder和ServletHolder,對所有FilterHolder的start按其定義順序進行,而對ServletHolder的start,則按其InitOrder排序。

          doScope方法實現

          doScope方法用于準備執行環境,其實現邏輯為:如果傳入的target不是ServletName(即以"/"開頭,表示它為Path),則使用該target從_servletPathMap中找到對應的ServletHolder,并計算出當前的ServletPath和PathInfo,如果時INCLUDE類型的Dispatch,設置Request的javax.servlet.include.serlvet_path,javax.servlet.include.path_info屬性為計算出來的值,否則設置Request的ServletPath和PathInfo的值為計算出的值;對target為ServletName,ServletHolder的實例從_servletNameMap字段中查找。然后將當前找到的ServletHolder作為UserIdentityScope設置到Request中,以及設置org.eclipse.multipartConfig屬性為ServletHolder中的MultipartConfig實例。在剛方法退出時,將UserIdentityScope、ServletPath、PathInfo還原回原來的值。

          doHandle方法實現

          doHandle方法用于真正實現執行邏輯:它首先通過target找到FilterChain實例,對于target為path時,它遍歷整個_filterPathMapping的列表,選出所有符合pathInContext的FilterHolder數組,以及從_filterNameMappings中找出所有ServletHolder中存儲的ServletName對應的FilterMapping并且DispatcherType相符合的FilterMapping數組,以及注冊的ServletName為"*"的FilterMapping且DispatcherType相符的FilterMapping數組,合并這些數組,并一同用Request、ServletHolder創建FilterChain實例;對target為ServletName時,只需要查找_filterNameMapping字段中的FilterMapping。如果沒有FilterHolder實例,則向客戶端發送404 Not Found響應;否則如果FilterChain實例不為null,調用其doFilter方法,傳入ServletRequest和ServletResponse參數,在FilterChain的doFilter方法中它回一次遍歷Filter的doFilter方法,直到最后調用ServletHolder的handle方法;否則,直接調用ServletHolder的handle方法。
          posted on 2014-05-17 23:20 DLevin 閱讀(1953) 評論(1)  編輯  收藏 所屬分類: Jetty

          FeedBack:
          # re: 深入Jetty源碼之ServletHandler
          2014-05-18 15:14 | 金利鎖業
          謝謝 博主分享  回復  更多評論
            
          主站蜘蛛池模板: 宝兴县| 固始县| 金秀| 大冶市| 阿拉善盟| 东乡族自治县| 洞口县| 关岭| 内乡县| 荔浦县| 台江县| 当雄县| 文化| 永清县| 龙井市| 蓝田县| 南投市| 中阳县| 新疆| 石景山区| 三河市| 横山县| 夏津县| 青海省| 盈江县| 余干县| 曲阳县| 彝良县| 牙克石市| 崇州市| 和平区| 惠安县| 台南县| 滨海县| 保山市| 六枝特区| 客服| 长岛县| 六安市| 阜阳市| 泰州市|