Jetty - Handler源码分析
1. 描述
基于Jetty-9.4.8.v20171121。
Handler是Jetty服务处理器,用户Server处理HTTP请求。
Handler可以做如下处理:
(1)完全生成HTTP响应;
(2)检查或修改请求然后调用其他Handler,比如HandlerWrapper;
(3)传递请求给一个或多个Handlers,比如HandlerCollection;
1.1 类图
(1)AbstractHandler继承ContainerLifeCycle提供:
(a)启停行为
(b)bean容器
(c)基本的dump支持
(d)Server引用
(e)ErrorDispatchHandler处理错误
(2)实现HandlerContainer接口的Handler可以包含其他Handlers,可以是一个HandlerWrapper或多个HandlerList/HandlerCollection;
(3)HandlerWapper是一个装饰器模式的装饰类,其子类如GzipHandler,ResourceHandler实现不同的装饰效果,如下类图:
// 装饰器模式 -- 核心类 class Decorator implements Component { private Component component; // 维持一个对抽象构件对象的引用 public Decorator(Component component) // 注入一个抽象构件类型的对象 { this.component=component; } public void operation() { component.operation(); //调用原有业务方法 } }
(4)HandlerCollection和HandlerList包含多个Handler。
1.2 API
@ManagedObject("Jetty Handler") public interface Handler extends LifeCycle, Destroyable { /** * Handle a request. * * @param target * The target of the request - either a URI or a name. * @param baseRequest * The original unwrapped request object. * @param request * The request either as the {@link Request} object or a wrapper of that request. The * <code>{@link HttpConnection#getCurrentConnection()}.{@link HttpConnection#getHttpChannel() getHttpChannel()}.{@link HttpChannel#getRequest() getRequest()}</code> * method can be used access the Request object if required. * @param response * The response as the {@link Response} object or a wrapper of that request. The * <code>{@link HttpConnection#getCurrentConnection()}.{@link HttpConnection#getHttpChannel() getHttpChannel()}.{@link HttpChannel#getResponse() getResponse()}</code> * method can be used access the Response object if required. * @throws IOException * if unable to handle the request or response processing * @throws ServletException * if unable to handle the request or response due to underlying servlet issue */ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException; public void setServer(Server server); @ManagedAttribute(value="the jetty server for this handler", readonly=true) public Server getServer(); @ManagedOperation(value="destroy associated resources", impact="ACTION") public void destroy(); }
2. AbstractHandler
AbstractHandler是Handler的基本实现。
// 实现ContainerLifeCycle提供基本能力:(1)启停行为(2)bean容器化(3)基本的dump支持(4)Server引用(5)错误处理Handler @ManagedObject("Jetty Handler") public abstract class AbstractHandler extends ContainerLifeCycle implements Handler { private static final Logger LOG = Log.getLogger(AbstractHandler.class); private Server _server; // Server public AbstractHandler() { } @Override public abstract void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException; // 生成错误页面,当DispatchType.ERROR,handle可以调用该方法 protected void doError(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { Object o = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); int code = (o instanceof Integer)?((Integer)o).intValue():(o!=null?Integer.valueOf(o.toString()):500); o = request.getAttribute(RequestDispatcher.ERROR_MESSAGE); String reason = o!=null?o.toString():null; response.sendError(code,reason); } /* * @see org.eclipse.thread.LifeCycle#start() */ @Override protected void doStart() throws Exception { if (LOG.isDebugEnabled()) LOG.debug("starting {}",this); if (_server==null) LOG.warn("No Server set for {}",this); super.doStart(); } /* * @see org.eclipse.thread.LifeCycle#stop() */ @Override protected void doStop() throws Exception { if (LOG.isDebugEnabled()) LOG.debug("stopping {}",this); super.doStop(); } @Override public void setServer(Server server) { if (_server==server) return; if (isStarted()) throw new IllegalStateException(STARTED); _server=server; } @Override public Server getServer() { return _server; } @Override public void destroy() { if (!isStopped()) throw new IllegalStateException("!STOPPED"); super.destroy(); } @Override public void dumpThis(Appendable out) throws IOException { out.append(toString()).append(" - ").append(getState()).append('\n'); } // 处理DispatcherType.ERROR的分发 public static abstract class ErrorDispatchHandler extends AbstractHandler { @Override public final void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { if (baseRequest.getDispatcherType()==DispatcherType.ERROR) doError(target,baseRequest,request,response); else doNonErrorHandle(target,baseRequest,request,response); } // 处理所有非DispatcherType.ERROR protected abstract void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException; } }
3. HandlerWrapper
HandlerWrapper实现的是一个典型的装饰器模式。
@Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { Handler handler=_handler; // 被装饰对象的handle方法 if (handler!=null) handler.handle(target,baseRequest, request, response); }
4. HandlerCollection
Handlers集合,默认实现是按照顺序执行所有handle方法,不管响应码和异常。子类可以改变调用顺序或者调用规则
@ManagedObject("Handler of multiple handlers") public class HandlerCollection extends AbstractHandlerContainer { private final boolean _mutableWhenRunning; private volatile Handler[] _handlers; @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { if (_handlers!=null && isStarted()) { MultiException mex=null; for (int i=0;i<_handlers.length;i++) // 依次调用handle方法 { try { _handlers[i].handle(target,baseRequest, request, response); } catch(IOException e) { throw e; } catch(RuntimeException e) { throw e; } catch(Exception e) { if (mex==null) mex=new MultiException(); mex.add(e); } } if (mex!=null) { if (mex.size()==1) throw new ServletException(mex.getThrowable(0)); else throw new ServletException(mex); } } } }
5. HandlerList
继承HandlerCollection,调用每一个Handler,遇到3种情况会退出:(1)抛出异常(2)响应被提交(3)整数的响应状态
@Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException // 异常退出 { Handler[] handlers = getHandlers(); if (handlers!=null && isStarted()) { for (int i=0;i<handlers.length;i++) { handlers[i].handle(target,baseRequest, request, response); if ( baseRequest.isHandled()) // 退出 return; } } }
总的来说,Handler采用装饰器模式,通过继承父装饰类,自定义不同的handlr处理逻辑。