• Jetty


    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('
    ');
        }
    
         // 处理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处理逻辑。

  • 相关阅读:
    插件开发取路径
    使用SWT模拟鼠标键盘事件
    简单RCP框架源码分析
    dom4j中使用xpath解析带命名空间的xml文件,取不到节点的解决办法
    log4j不能输出配置文件问题的解决。
    SWT中定时器的一种特殊实现方式/SWT中线程互访时display.asyncExec/display.syncExec...程序死掉无响应的解决办法
    Eclipse插件开发中对于外部Jar包和类文件引用的处理(彻底解决插件开发中的NoClassDefFoundError问题)
    zk 3.6数据绑定
    PythonExcel 模块对比
    去除数组中重复元素
  • 原文地址:https://www.cnblogs.com/lujiango/p/8416960.html
Copyright © 2020-2023  润新知