Handler概述
Handler是Jetty中的核心接口,它用于處理所有連接以外的邏輯,比如對(duì)Servlet框架的實(shí)現(xiàn),以及用戶自定義的Handler等,它繼承自LifeCycle和Destroyable接口,只有一個(gè)主要方法:handle,包含Request和Response實(shí)例。在
深入Jetty源碼之Connection中有寫道在HttpConnection的handleRequest()方法中會(huì)最終調(diào)用Server的handle()或handleAsync()方法,并且傳入HttpConnection自身作為參數(shù)以處理后續(xù)邏輯,在這里Server作為Handler的容器,在Server中以HttpConnection為參數(shù)的handle()和handleAsync()方法中,會(huì)調(diào)用向這個(gè)Handler容器中注冊(cè)的所有Handler的handle()方法。即在使用Jetty時(shí),我們首先要向Server注冊(cè)相應(yīng)的Handler實(shí)例。
Handler接口定義
Handler的接口定義如下:
public interface Handler extends LifeCycle, Destroyable {
// 處理一個(gè)HTTP請(qǐng)求,并最終將響應(yīng)寫入Response中。不同的實(shí)現(xiàn)有不同的功能和邏輯,如WebAppContext實(shí)現(xiàn)一個(gè)Servlet容器,
// 而ErrorHandler則向Response中寫入一個(gè)包含錯(cuò)誤碼和原因的HTML頁面。
// 關(guān)于參數(shù):
// target表示Request的目標(biāo),它可以時(shí)一個(gè)URI或一個(gè)名字。即Request中的pathInfo字段。
// baseRequest表示在HttpConnection中創(chuàng)建并解析的最初的Request,它沒有被包裝。
// request表示一個(gè)HttpServletRequest,它可以同baseRequest相同的實(shí)例,也可以是一個(gè)經(jīng)過包裝后的HttpServletRequest。
// response表示一個(gè)HttpServletResponse,它可以是經(jīng)過包裝的HttpServletResponse或在HttpConnection創(chuàng)建的最原始的HttpServletResponse。
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException;
public void setServer(Server server);
public Server getServer();
public void destroy();
}
Handler類圖

AbstractHandler
AbstractHandler繼承自AggregateLifeCycle并實(shí)現(xiàn)了Handler接口,是基本上所有Handler的基類。它的實(shí)現(xiàn)也非常簡(jiǎn)單,它定義了Server成員,并實(shí)現(xiàn)了getServer和setServer方法,在setServer實(shí)現(xiàn)中,如果已存在的Server引用和新設(shè)置的Server不同,則先將自身從已存在的Server的Container中移除,然后將自身添加到新的Server的Container中,并更新內(nèi)部對(duì)Server的引用實(shí)例。在destroy方法中,也會(huì)將自身從Server引用實(shí)例的Container中移除。
DefaultHandler
DefaultHandler直接繼承自AbstractHandler,它可以用于Handler鏈表的末尾Handler,用于處理所有不能被其他Handler處理的請(qǐng)求:/favicon.ico -> 顯示jetty圖標(biāo),/ -> 顯示404錯(cuò)誤頁面,并列出所有可用的ContextPath,任何其他請(qǐng)求顯示404錯(cuò)誤頁面。圖標(biāo)的顯示和可用ContextPath的列表顯示都是可配的。
DumpHandler
DumpHandler直接繼承自AbstractHandler,用于測(cè)試和調(diào)試,顯示Request消息內(nèi)容。它顯示的信息有PathInfo、ContentType、CharacterEncoding、RequestLine、Headers、Parameters、CookieName、Cookies、Attributes、Content等。
ErrorHandler
ErrorHandler直接繼承自AbstractHandler,用于處理錯(cuò)誤頁面,使用ContextHandler.setErrorHandler()或Server.addBean()注冊(cè)。它顯示出錯(cuò)代碼、原因以及更詳細(xì)的信息。其中異常棧從Request的javax.servlet.errro.exception中獲取。
ErrorPageErrorHandler
ErrorPageErrorHandler繼承自ErrorHandler,它可以配置不同的Exception和Response Status Code到不同的頁面。Exception類型從Request中的javax.servlet.error.exception_type或javax.servlet.error.exception屬性中獲取,Response Status Code從Request中的javax.servlet.error.status_code屬性中獲取。使用Exception類型、Response Status Code、Response Status Code Range從_errorPages中查找在web.xml文件中注冊(cè)的映射,如果有找到,則使用ServletContext中的RequestDispatcher將當(dāng)前的Request、Response派發(fā)的其error處理邏輯;否則使用ErrorHandler中的邏輯。
ResourceHandler
ResourceHandler直接繼承自AbstractHandler,用于處理靜態(tài)資源以及If-Modified-Since頭。使用PathInfo以及注冊(cè)的或ContextHandler中的BaseResource作為Base查找Resource,如果找不到并且請(qǐng)求的類型是/jetty-stylesheet.css資源,則查找注冊(cè)的或默認(rèn)的stylesheet資源;如果查找到的資源是目錄,如果URL不是以"/"結(jié)尾,則重定向到"URL/",否則查找是否有welcome list中配置的頁面存在以顯示,否則列出文件列表或者顯示403 Forbidden頁面;對(duì)If-Modified-Since請(qǐng)求頭,如果資源存在LastModified屬性,并且比請(qǐng)求中設(shè)置的值要小或相等(以秒為單位),返回304 Not Modified;根據(jù)文件名或PathInfo以及注冊(cè)的MineTypes信息設(shè)置ContentType,設(shè)置Content-Length、Cache-Control、Last-Modified等響應(yīng)頭,將Resource內(nèi)容寫入Response中。
順便提及:Resource是Jetty中對(duì)靜態(tài)資源的抽象,其子類有URLResource、FileResource、JarResource、JarFileResource、BadResource等。類似
Spring中對(duì)Resource抽象,不詳述。
AbstractHandlerContainer
AbstractHandlerContainer繼承自AbstractHandler,并實(shí)現(xiàn)了HandlerContainer接口。HandlerContainer接口定義如下:
public interface HandlerContainer extends LifeCycle {
// 返回當(dāng)前Handler包含的所有Handler
public Handler[] getHandlers();
// 返回當(dāng)前Handler和其所有子Handler包含的所有Handler
public Handler[] getChildHandlers();
// 返回所有當(dāng)前Handler和其所有子Handler包含的所有Handler中類型為指定類型的Handler
public Handler[] getChildHandlersByClass(Class<?> byclass);
// 返回第一個(gè)所有當(dāng)前Handler和其所有子Handler包含的所有Handler中類型為指定類型的Handler
public <T extends Handler> T getChildHandlerByClass(Class<T> byclass);
}
AbstractHandlerContainer主要實(shí)現(xiàn)了兩個(gè)方法:
// 將所有當(dāng)前handler或其子handler中類型為byClass的Handler添加到list中,并返回該list實(shí)例
protected Object expandHandler(Handler handler, Object list, Class<Handler> byClass);
// 從root的HandlerContainer中找到handler所在的HandlerContainer實(shí)例,并且該HandlerContainer必須屬于type類型
public static <T extends HandlerContainer> T findContainerOf(HandlerContainer root,Class<T>type, Handler handler);
HandlerCollection
HandlerCollection繼承自AbstractHandlerContainer,它使用Handler數(shù)組作為容器來存儲(chǔ)Handler,并且可已配置是否在啟動(dòng)后還能修改這個(gè)容器,以及啟動(dòng)是是否并行啟動(dòng):
private final boolean _mutableWhenRunning;
private volatile Handler[] _handlers;
private boolean _parallelStart=false;
在handle()方法實(shí)現(xiàn)中,遍歷數(shù)組中所有的Handler,調(diào)用其handle()方法。
在setHandlers()和setServer()方法實(shí)現(xiàn)中,需要生成并分發(fā)handler的Relationship發(fā)生變化的事件給在Server中的Container中注冊(cè)的Listener,以及更新相應(yīng)Handler中對(duì)Server的引用。
HandlerList
它繼承自HandlerCollection,只是重寫了handle()方法的邏輯,即在HandlerList中,它遍歷整個(gè)Handlers
數(shù)組直到有異常發(fā)生或baseRequest的isHandled()返回true(什么時(shí)候baseRequest的handled屬性會(huì)被設(shè)置為true呢?在發(fā)送請(qǐng)求之前或相應(yīng)狀態(tài)碼被設(shè)置);而HandlerCollection則會(huì)遍歷整個(gè)Handlers數(shù)組直到一個(gè)RuntimeException發(fā)生或IOException發(fā)生或整個(gè)Handler數(shù)組遍歷完成,如果中途有出現(xiàn)其他異常最后統(tǒng)一拋出。
ContextHandlerCollection
ContextHandlerCollection繼承自HandlerCollection,使用PathMap存儲(chǔ)請(qǐng)求URI到ContextHandler的映射。
HotSwapHandler
HotSwapHandler繼承自AbstractHandlerContainer,支持動(dòng)態(tài)的替換內(nèi)部的Handler(即在設(shè)置Handler時(shí),如果當(dāng)前Handler已經(jīng)啟動(dòng),則并立即啟動(dòng)新設(shè)置的Handler,并停止原來的Handler)。它使用Composite模式,內(nèi)部只是使用一個(gè)Handler來保存一個(gè)集合的Handler,因而如果要注冊(cè)多個(gè)Handler,則這個(gè)Handler的類型需要HandlerContainer。
HandlerWrapper
HandlerWrapper繼承自AbstractHandlerContainer,它類似Composite模式,使用一個(gè)Handler本身來表達(dá)一個(gè)HandlerContainer,因而同HotSwapHandler,它只是包含一個(gè)Handler字段用與表示、存儲(chǔ)Handler集合,并且其實(shí)現(xiàn)也和HotSwapHandler類似,所不同的是它不會(huì)動(dòng)態(tài)的啟動(dòng)新設(shè)置的Handler,即它只是一個(gè)Handler的Wrapper。
ConnectHandler
ConnectHandler繼承自HandlerWrapper,它實(shí)現(xiàn)了一個(gè)代理服務(wù)器。
DebugHandler
DebugHandler繼承自HandlerWrapper,用于測(cè)試時(shí)使用,在logs
目錄中yyyy_mm_dd.debug.log文件的形式紀(jì)錄請(qǐng)求的時(shí)間和URL以及響應(yīng)的時(shí)間和響應(yīng)狀態(tài)碼,并設(shè)置線程名為請(qǐng)求URL。
IPAccessHandler
IPAccessHandler繼承自HandlerWrapper,用于添加可以使用或需要組織的IP列表,并返回403 Forbidden響應(yīng)。
RequestLogHandler
RequestLogHandler繼承自HandlerWrapper,在所有handler處理結(jié)束后,將Request和Response使用RequestLog類打印到日志中。
StatisticsHandler
StatisticsHandler繼承自HandlerWrapper,用于紀(jì)錄一些統(tǒng)計(jì)信息,如請(qǐng)求數(shù)、請(qǐng)求時(shí)間、dispatched數(shù)與時(shí)間、suspended數(shù)、resume數(shù)、expire數(shù)、1xx到5xx的響應(yīng)數(shù)、響應(yīng)總的字節(jié)數(shù)等。
posted on 2014-05-06 22:56
DLevin 閱讀(4053)
評(píng)論(1) 編輯 收藏 所屬分類:
Jetty