概述
ServletHandler繼承自ScopedHandler,是Jetty中用于存儲所有Filter、FilterMapping、Servlet、ServletMapping的地方,以及用于實現(xiàn)一次請求所對應的Filter鏈和Servlet執(zhí)行流程的類。對Servlet的框架實現(xiàn)中,它也被認為是Handler鏈的末端,因而在它的doHandle()方法中沒有調(diào)用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的實現(xiàn));而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規(guī)則和FilterMapping中的規(guī)則一樣:
private String _servletName;
private String[] _pathSpecs;
在管理Filter和FilterMapping中,可以使用FilterHolder、pathSpec、DispatcherType向_filters數(shù)組中添加一個FilterHolder,并向_filterMappings數(shù)組中添加一個FilterMapping實例;而由該方法引申出來的,可以直接傳入Filter實例、Filter類實例、Filter類名,而由方法內(nèi)部創(chuàng)建對應的FilterHolder實例;DispatcherType可以是一個EnumSet類型的DispatcherType;可以直接添加Filter或FilterMapping或兩個同時添加;也可以使用prependFilterMapping將新的FilterMapping添加到數(shù)組前。對Servlet和ServletMapping管理也是類似,使用ServletHolder和pathSpec添加_servlets數(shù)組和_servletMappings數(shù)組,并引申出Servlet可以是實例、Servlet類名、Servlet類實例,而由內(nèi)部創(chuàng)建ServletHolder實例;也可以單獨的添加ServletHolder或ServletMapping實例。
在ServletHandler中還有_filterNameMap和_servletNameMap實例用于存儲FilterName到FilterHolder以及ServletName到ServletHolder的映射,它在每次_filters、_servlets數(shù)組更新時都會隨著更新,并且在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方法實現(xiàn)
doScope方法用于準備執(zhí)行環(huán)境,其實現(xiàn)邏輯為:如果傳入的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方法實現(xiàn)
doHandle方法用于真正實現(xiàn)執(zhí)行邏輯:它首先通過target找到FilterChain實例,對于target為path時,它遍歷整個_filterPathMapping的列表,選出所有符合pathInContext的FilterHolder數(shù)組,以及從_filterNameMappings中找出所有ServletHolder中存儲的ServletName對應的FilterMapping并且DispatcherType相符合的FilterMapping數(shù)組,以及注冊的ServletName為"*"的FilterMapping且DispatcherType相符的FilterMapping數(shù)組,合并這些數(shù)組,并一同用Request、ServletHolder創(chuàng)建FilterChain實例;對target為ServletName時,只需要查找_filterNameMapping字段中的FilterMapping。如果沒有FilterHolder實例,則向客戶端發(fā)送404 Not Found響應;否則如果FilterChain實例不為null,調(diào)用其doFilter方法,傳入ServletRequest和ServletResponse參數(shù),在FilterChain的doFilter方法中它回一次遍歷Filter的doFilter方法,直到最后調(diào)用ServletHolder的handle方法;否則,直接調(diào)用ServletHolder的handle方法。
posted on 2014-05-17 23:20
DLevin 閱讀(1947)
評論(1) 編輯 收藏 所屬分類:
Jetty