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的引用。