1. 描述

基于Jetty-9.4.8.v20171121。

Handler是Jetty服务处理器,用户Server处理HTTP请求。

Handler可以做如下处理:

(1)完全生成HTTP响应;

(2)检查或修改请求然后调用其他Handler,比如HandlerWrapper;

(3)传递请求给一个或多个Handlers,比如HandlerCollection;

1.1 类图

Jetty - Handler源码分析-LMLPHP

(1)AbstractHandler继承ContainerLifeCycle提供:

  (a)启停行为

  (b)bean容器

  (c)基本的dump支持

  (d)Server引用

  (e)ErrorDispatchHandler处理错误

(2)实现HandlerContainer接口的Handler可以包含其他Handlers,可以是一个HandlerWrapper或多个HandlerList/HandlerCollection;

(3)HandlerWapper是一个装饰器模式的装饰类,其子类如GzipHandler,ResourceHandler实现不同的装饰效果,如下类图:

Jetty - Handler源码分析-LMLPHP

// 装饰器模式 -- 核心类
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处理逻辑。

05-16 11:17