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处理逻辑。

Jetty - Handler源码分析的更多相关文章

  1. Jetty - Container源码分析

    1. 描述 Container提供管理bean的能力. 基于Jetty-9.4.8.v20171121. 1.1 API public interface Container { // 增加一个bea ...

  2. Jetty 9 源码分析 Connector及Server类(一)

    本文的源码基于Jetty9,主要分析了Jetty 的Connector与Server类间在Jetty启动过程中的一些细节.Jetty9 对以前的Connector体系进行了重构, 结构与6和7都不同, ...

  3. Jetty - Connector源码分析

    1. 描述 基于Jetty-9.4.8.v20171121. Connector接受远程机器的连接和数据,允许应用向远程机器发送数据. 1.2 类图 从类图看出AbstractConnector继承C ...

  4. Jetty - LifeCycle源码分析

    1. 描述 基于Jetty-9.4.8.v20171121. LifeCycle主要管理Jetty里面通用组件的生命周期,比如组件启动中.启动.运行.停止中.停止等,实现该接口就可以定义一套生命周期. ...

  5. Handler 源码分析

    Handler用法: 无参 Handler 构造函数实例化一个 Handler 类型的全局变量,并重写其 handleMessage 方法,在某一方法内调用 Handler 的 sendEmptyMe ...

  6. Android之Handler源码深入分析

    闲着没事,就来看看源码,看看源码的各种原理,会用只是简单的,知道为什么才是最牛逼的. Handler源码分析那,从使用的步骤来边用边分析: 1.创建一个Handler对象:new Handler(ge ...

  7. Android异步消息传递机制源码分析

    1.Android异步消息传递机制有以下两个方式:(异步消息传递来解决线程通信问题) handler 和 AsyncTask 2.handler官方解释的用途: 1).定时任务:通过handler.p ...

  8. 【Android】Handler、Looper源码分析

    一.前言 源码分析使用的版本是 4.4.2_r1. Handler和Looper的入门知识以及讲解可以参考我的另外一篇博客:Android Handler机制 简单而言:Handler和Looper是 ...

  9. jetty加载spring-context容器源码分析

    带着疑问开始 web.xml的顺序问题 先拿一个最简单的spring mvc web.xml来说问题,如下图:如果我将三者的顺序倒置或是乱置,会产生什么结果呢? 启动报错?还是加载未知结果?还是毫无影 ...

随机推荐

  1. Android显示GIF动画 GifView

    android中显示gif动画原生态一般支持的不是很好,故找了一个开源的项目,现简单介绍如下: GifView 是一个为了解决android中现在没有直接显示gif的view,只能通过mediapla ...

  2. jQuery Ajax 参数解析

    简单的例子: $.ajax({ type:"post", data:{a:acon,b:bcon} , url:"ajax.php", async:false ...

  3. cas服务器源码阅读笔记,对标博客

    对标源码阅读博客:http://www.cnblogs.com/jiuzhongguo/category/375405.html 在CAS中很多地方使用了策略模式,那么根据什么方式来确定使用哪种策略呢 ...

  4. sonar如何添加自定义JAVA规则

    参考: 1.https://segmentfault.com/a/1190000008659108 2.https://docs.sonarqube.org/display/DEV/Adding+Co ...

  5. ylbtech-LanguageSamples-PartialTypes(部分类型)

    ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-PartialTypes(部分类型) 1.A,示例(Sample) 返回顶部 “分部类型 ...

  6. 微软对外披露两个0day漏洞详情

    微软近日对外披露了两个0day漏洞详情,其中一个漏洞存在Adobe阅读器中,可被利用导致任意代码执行:另一个漏洞则允许任意代码在Windows kernel内存中提权执行. 微软称由于该漏洞利用目前还 ...

  7. ubuntu 不是 识别 android 设备 解决方法

    ubuntu: 在终端输入lsusb: langu@langu:~$ lsusb Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root ...

  8. 转: windows下C++ UI库 UI神器-SOUI

    转:http://www.cnblogs.com/setoutsoft/p/4996870.html 前言 在Windows平台上开发客户端产品是一个非常痛苦的过程,特别是还要用C++的时候.尽管很多 ...

  9. 几个免费的DNS地址

    百度CDN 180.76.76.76 114.114.114.114 阿里CDN 223.5.5.5 223.6.6.6 googleCDN 8.8.8.8 国内外DNSserver地址列表 http ...

  10. JMeter 三:搭建一个Web Test Plan

    参考:http://jmeter.apache.org/usermanual/build-web-test-plan.html 场景 5个用户并发测试百度搜索,有两个请求,一个请求搜索“你好”,一个请 ...