Jetty 的 connector 负责建立连接,具体处理请求的工作就是由 handler 完成。
connector 调用 handler 处理请求,handler 调用 servlet 完成请求,同时还负责 servlet的生命周期。
这就是 servlet 容器的本质!

Jetty 的 Handler 在设计上非常有意思,可以说是 Jetty 的灵魂。
Jetty 通过 Handler 实现了高度可定制化,那具体是如何实现的呢?

Handler

Handler 就是一个接口,它有一堆实现类,Jetty 的 Connector 组件调用这些接口来处理 Servlet 请求。
image.png
Handler 接口的定义如下:

  1. public interface Handler extends LifeCycle, Destroyable
  2. {
  3. //处理请求的方法
  4. public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
  5. throws IOException, ServletException;
  6. //每个Handler都关联一个Server组件,被Server管理
  7. public void setServer(Server server);
  8. public Server getServer();
  9. //销毁方法相关的资源
  10. public void destroy();
  11. }

任何一个 Handler 都需要关联一个 Server 组件,也就是说 Handler 需要被 Server 组件来管理。

Handler 类层次

Handler 接口有抽象实现类 AbstractHandler。
AbstractHandler 之下有 AbstractHandlerContainer。为什么需要这个类呢?其实是为了实现链式调用。
一个 Handler 内部必然要有其他 Handler 的引用,这个类才叫HandlerContainer。
HandlerWrapper 和 HandlerCollection 都是 HandlerContainer,包含其他 Handler 的引用
image.png
image.png

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 应用 ?

  1. //新建一个WebAppContext,WebAppContext是一个Handler
  2. WebAppContext webapp = new WebAppContext();
  3. webapp.setContextPath("/mywebapp");
  4. webapp.setWar("mywebapp.war");
  5. //将Handler添加到Server中去
  6. server.setHandler(webapp);
  7. //启动Server
  8. server.start();
  9. 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 中,这体现了“微内核 + 插件”的设计思想。