Jetty 的 connector 负责建立连接,具体处理请求的工作就是由 handler 完成。
connector 调用 handler 处理请求,handler 调用 servlet 完成请求,同时还负责 servlet的生命周期。
这就是 servlet 容器的本质!
Jetty 的 Handler 在设计上非常有意思,可以说是 Jetty 的灵魂。
Jetty 通过 Handler 实现了高度可定制化,那具体是如何实现的呢?
Handler
Handler 就是一个接口,它有一堆实现类,Jetty 的 Connector 组件调用这些接口来处理 Servlet 请求。
Handler 接口的定义如下:
public interface Handler extends LifeCycle, Destroyable
{
//处理请求的方法
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException;
//每个Handler都关联一个Server组件,被Server管理
public void setServer(Server server);
public Server getServer();
//销毁方法相关的资源
public void destroy();
}
任何一个 Handler 都需要关联一个 Server 组件,也就是说 Handler 需要被 Server 组件来管理。
Handler 类层次
Handler 接口有抽象实现类 AbstractHandler。
AbstractHandler 之下有 AbstractHandlerContainer。为什么需要这个类呢?其实是为了实现链式调用。
一个 Handler 内部必然要有其他 Handler 的引用,这个类才叫HandlerContainer。
HandlerWrapper 和 HandlerCollection 都是 HandlerContainer,包含其他 Handler 的引用
HandlerWrapper
Server
Server 本身是 Handler 模块的入口,必然包含其他 handler 的引用,将请求传递给其他 Handler 来处理。
Scopedhandler
Servlet 规范规定 Servlet 在执行过程中是有上下文的。ScopedHandler 有一堆的子类,这些子类就是用来实现 Servlet 规范的。ScopedHandler 的子类 ServletHandler、ContextHandler、SessionHandler、ServletContextHandler 和 WebAppContext。
HandlerCollection
为什么要发明一个这样的 Handler?
因为 Jetty 可能需要同时支持多个 Web 应用,如果每个 Web 应用有一个 Handler 入口,那么多个 Web 应用的 Handler 就成了一个数组,比如 Server 中就有一个 HandlerCollection,Server 会根据用户请求的 URL 从数组中选取相应的 Handler 来处理请求。
Handler 类型
协调 Handler:负责将请求路由到 HandlerCollection,然后请求又被转发到 Handler 数组中的某一个 Handler。
过滤器 Handler:处理请求,之后再把请求转发到下一个 HandlerWrapper,其内部持有下一个 Handler 的引用。
继承了 HandlerWrapper 的 Handler 都具有过滤器的特征,比如 ContextHandler、SessionHandler 和 WebAppContext 等。
内容 Handler:真正调用 Servlet 来处理请求,生成响应的内容,比如 ServletHandler。如果浏览器请求的是一个静态资源,也有相应的 ResourceHandler 来处理这个请求,返回静态页面。
如何实现 Servlet 规范?
Servlet 规范中有 Context、Servlet、Filter、Listener 和 Session 等。
Jetty 要支持 Servlet 规范,就需要有相应的 Handler 来分别实现这些功能。
Jetty 如何启动 web 应用 ?
//新建一个WebAppContext,WebAppContext是一个Handler
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/mywebapp");
webapp.setWar("mywebapp.war");
//将Handler添加到Server中去
server.setHandler(webapp);
//启动Server
server.start();
server.join();
Jetty 设计了 3 个组件:ContextHandler、ServletHandler 和 SessionHandler 来实现 Servlet 规范中规定的功能,而 WebAppContext 本身就是一个 ContextHandler,另外它还负责管理 ServletHandler 和 SessionHandler。
什么是 ContextHandler ?
ContextHandler 会创建并初始化 Servlet 规范里的 ServletContext 对象,同时还包含了一组让 Web 应用运行起来的 Handler。
Context 本身也是一种 Handler,它里面包含了其他的 Handler,这些 Handler 能处理某个特定 URL 下的请求。
比如 ContextHandler 包含了一个或者多个 ServletHandler。因此 ContextHandler 也是 HandlerWrapper 的子类。
什么是 ServletHandler ?
ServletHandler 实现了 Servlet 规范中的 Servlet、Filter 和 Listener 的功能。
ServletHandler 有四大组件:FilterHolder、ServletHolder、ServletMapping、FilterMapping 。
FilterHolder 是 Filter 的包装类。FilterMapping 封装 Filter 与拦截 URL 的映射。
ServletHolder 是 Servlet 的包装类。ServletMapping 封装 Servlet 与 URL 的映射。
设计思想
Jetty 本质就是一个 Handler 管理器。
Jetty 本身就提供了一些默认 Handler 来实现 Servlet 容器的功能,也可以定义 Handler 来添加到 Jetty 中,这体现了“微内核 + 插件”的设计思想。