Handler概述
Handler是Jetty中的核心接口,它用于處理所有連接以外的邏輯,比如對Servlet框架的實現,以及用戶自定義的Handler等,它繼承自LifeCycle和Destroyable接口,只有一個主要方法:handle,包含Request和Response實例。在深入Jetty源碼之Connection中有寫道在HttpConnection的handleRequest()方法中會最終調用Server的handle()或handleAsync()方法,并且傳入HttpConnection自身作為參數以處理后續邏輯,在這里Server作為Handler的容器,在Server中以HttpConnection為參數的handle()和handleAsync()方法中,會調用向這個Handler容器中注冊的所有Handler的handle()方法。即在使用Jetty時,我們首先要向Server注冊相應的Handler實例。Handler接口定義
Handler的接口定義如下:public interface Handler extends LifeCycle, Destroyable {
// 處理一個HTTP請求,并最終將響應寫入Response中。不同的實現有不同的功能和邏輯,如WebAppContext實現一個Servlet容器,
// 而ErrorHandler則向Response中寫入一個包含錯誤碼和原因的HTML頁面。
// 關于參數:
// target表示Request的目標,它可以時一個URI或一個名字。即Request中的pathInfo字段。
// baseRequest表示在HttpConnection中創建并解析的最初的Request,它沒有被包裝。
// request表示一個HttpServletRequest,它可以同baseRequest相同的實例,也可以是一個經過包裝后的HttpServletRequest。
// response表示一個HttpServletResponse,它可以是經過包裝的HttpServletResponse或在HttpConnection創建的最原始的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();
}
// 處理一個HTTP請求,并最終將響應寫入Response中。不同的實現有不同的功能和邏輯,如WebAppContext實現一個Servlet容器,
// 而ErrorHandler則向Response中寫入一個包含錯誤碼和原因的HTML頁面。
// 關于參數:
// target表示Request的目標,它可以時一個URI或一個名字。即Request中的pathInfo字段。
// baseRequest表示在HttpConnection中創建并解析的最初的Request,它沒有被包裝。
// request表示一個HttpServletRequest,它可以同baseRequest相同的實例,也可以是一個經過包裝后的HttpServletRequest。
// response表示一個HttpServletResponse,它可以是經過包裝的HttpServletResponse或在HttpConnection創建的最原始的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并實現了Handler接口,是基本上所有Handler的基類。它的實現也非常簡單,它定義了Server成員,并實現了getServer和setServer方法,在setServer實現中,如果已存在的Server引用和新設置的Server不同,則先將自身從已存在的Server的Container中移除,然后將自身添加到新的Server的Container中,并更新內部對Server的引用實例。在destroy方法中,也會將自身從Server引用實例的Container中移除。DefaultHandler
DefaultHandler直接繼承自AbstractHandler,它可以用于Handler鏈表的末尾Handler,用于處理所有不能被其他Handler處理的請求:/favicon.ico -> 顯示jetty圖標,/ -> 顯示404錯誤頁面,并列出所有可用的ContextPath,任何其他請求顯示404錯誤頁面。圖標的顯示和可用ContextPath的列表顯示都是可配的。DumpHandler
DumpHandler直接繼承自AbstractHandler,用于測試和調試,顯示Request消息內容。它顯示的信息有PathInfo、ContentType、CharacterEncoding、RequestLine、Headers、Parameters、CookieName、Cookies、Attributes、Content等。ErrorHandler
ErrorHandler直接繼承自AbstractHandler,用于處理錯誤頁面,使用ContextHandler.setErrorHandler()或Server.addBean()注冊。它顯示出錯代碼、原因以及更詳細的信息。其中異常棧從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文件中注冊的映射,如果有找到,則使用ServletContext中的RequestDispatcher將當前的Request、Response派發的其error處理邏輯;否則使用ErrorHandler中的邏輯。ResourceHandler
ResourceHandler直接繼承自AbstractHandler,用于處理靜態資源以及If-Modified-Since頭。使用PathInfo以及注冊的或ContextHandler中的BaseResource作為Base查找Resource,如果找不到并且請求的類型是/jetty-stylesheet.css資源,則查找注冊的或默認的stylesheet資源;如果查找到的資源是目錄,如果URL不是以"/"結尾,則重定向到"URL/",否則查找是否有welcome list中配置的頁面存在以顯示,否則列出文件列表或者顯示403 Forbidden頁面;對If-Modified-Since請求頭,如果資源存在LastModified屬性,并且比請求中設置的值要小或相等(以秒為單位),返回304 Not Modified;根據文件名或PathInfo以及注冊的MineTypes信息設置ContentType,設置Content-Length、Cache-Control、Last-Modified等響應頭,將Resource內容寫入Response中。順便提及:Resource是Jetty中對靜態資源的抽象,其子類有URLResource、FileResource、JarResource、JarFileResource、BadResource等。類似Spring中對Resource抽象,不詳述。
AbstractHandlerContainer
AbstractHandlerContainer繼承自AbstractHandler,并實現了HandlerContainer接口。HandlerContainer接口定義如下:public interface HandlerContainer extends LifeCycle {
// 返回當前Handler包含的所有Handler
public Handler[] getHandlers();
// 返回當前Handler和其所有子Handler包含的所有Handler
public Handler[] getChildHandlers();
// 返回所有當前Handler和其所有子Handler包含的所有Handler中類型為指定類型的Handler
public Handler[] getChildHandlersByClass(Class<?> byclass);
// 返回第一個所有當前Handler和其所有子Handler包含的所有Handler中類型為指定類型的Handler
public <T extends Handler> T getChildHandlerByClass(Class<T> byclass);
}
AbstractHandlerContainer主要實現了兩個方法:// 返回當前Handler包含的所有Handler
public Handler[] getHandlers();
// 返回當前Handler和其所有子Handler包含的所有Handler
public Handler[] getChildHandlers();
// 返回所有當前Handler和其所有子Handler包含的所有Handler中類型為指定類型的Handler
public Handler[] getChildHandlersByClass(Class<?> byclass);
// 返回第一個所有當前Handler和其所有子Handler包含的所有Handler中類型為指定類型的Handler
public <T extends Handler> T getChildHandlerByClass(Class<T> byclass);
}
// 將所有當前handler或其子handler中類型為byClass的Handler添加到list中,并返回該list實例
protected Object expandHandler(Handler handler, Object list, Class<Handler> byClass);
// 從root的HandlerContainer中找到handler所在的HandlerContainer實例,并且該HandlerContainer必須屬于type類型
public static <T extends HandlerContainer> T findContainerOf(HandlerContainer root,Class<T>type, Handler handler);
protected Object expandHandler(Handler handler, Object list, Class<Handler> byClass);
// 從root的HandlerContainer中找到handler所在的HandlerContainer實例,并且該HandlerContainer必須屬于type類型
public static <T extends HandlerContainer> T findContainerOf(HandlerContainer root,Class<T>type, Handler handler);
HandlerCollection
HandlerCollection繼承自AbstractHandlerContainer,它使用Handler數組作為容器來存儲Handler,并且可已配置是否在啟動后還能修改這個容器,以及啟動是是否并行啟動: private final boolean _mutableWhenRunning;
private volatile Handler[] _handlers;
private boolean _parallelStart=false;
在handle()方法實現中,遍歷數組中所有的Handler,調用其handle()方法。private volatile Handler[] _handlers;
private boolean _parallelStart=false;
在setHandlers()和setServer()方法實現中,需要生成并分發handler的Relationship發生變化的事件給在Server中的Container中注冊的Listener,以及更新相應Handler中對Server的引用。