• Jetty:开发指导Handlers


    Rewrite Handler

    RewriteHandler匹配一个基于该请求的规则集合,然后根据匹配规则的变更请求。

    最常见的要求是改写URI。但不限于:规则可以被配置为重定向响应、设置cookie或响应码响应、变化header。等等。

    高速開始

    标准Jetty公布中包括jetty-rewrite模块JAR,在lib/jetty-rewrite-*.jar,和一个样例配置文件,在etc/jetty-rewrite.xml。

    为了激活重写模块,用样例配置文件。用例如以下命令启动Jetty:

    $ java -jar start.jar OPTIONS=default,rewrite etc/jetty.xml etc/jetty-rewrite.xml 

    注意:假设你正在使用样例test webapp执行标准Jetty公布。有一个重写模块的demo在http://localhost:8080/rewrite/

    配置Rules

    rules通过使用jetty.xml配置。

    以下的样例文件展示怎么为server添加重写handler:

    <Configure id="Server" class="org.eclipse.jetty.server.Server">
        <!-- create and configure the rewrite handler -->
        <New id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RewriteHandler">
          <Set name="rewriteRequestURI">true</Set>
          <Set name="rewritePathInfo">false</Set>
          <Set name="originalPathAttribute">requestedPath</Set>
      
          <!-- redirect the response. This is a redirect which is visible to the browser.
               After the redirect, the browser address bar will show /redirected -->
          <Call name="addRule">
            <Arg>
              <New class="org.eclipse.jetty.rewrite.handler.RedirectPatternRule">
                <Set name="pattern">/redirect/*</Set>
                <Set name="replacement">/redirected</Set>
              </New>
            </Arg>
          </Call>
      
          <!-- rewrite the request URI. This is an internal rewrite, visible to server,
               but the browser will still show /some/old/context -->
          <Call name="addRule">
            <Arg>
              <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
                <Set name="pattern">/some/old/context</Set>
                <Set name="replacement">/some/new/context</Set>
              </New>
            </Arg>
          </Call>
      
          <!-- reverse the order of the path sections. Internal rewrite -->
          <Call name="addRule">
            <Arg>
              <New class="org.eclipse.jetty.rewrite.handler.RewriteRegexRule">
                <Set name="regex">/reverse/([^/]*)/(.*)</Set>
                <Set name="replacement">/reverse/$2/$1</Set>
              </New>
            </Arg>
          </Call>
        </New>
      
         <!-- add the rewrite handler to the server -->
        <Set name="handler"><Ref id="Rewrite" /></Set>
    </Configure>

    很多其它的配置样例请看etc/jetty-rewrite.xml。

    嵌入的样例

    以下是嵌入Jetty的一个样例,和上面的配置文件做相同的事情:

    Server server = new Server();
     
    RewriteHandler rewrite = new RewriteHandler();
    rewrite.setRewriteRequestURI(true);
    rewrite.setRewritePathInfo(false);
    rewrite.originalPathAttribute("requestedPath");
     
    RedirectPatternRule redirect = new RedirectPatternRule();
    redirect.setPattern("/redirect/*");
    redirect.setReplacement("/redirected");  
    rewrite.addRule(redirect);
     
    RewritePatternRule oldToNew = new RewritePatternRule();
    oldToNew.setPattern("/some/old/context");
    oldToNew.setReplacement("/some/new/context");
    rewrite.addRule(oldToNew);
     
    RewriteRegexRule reverse = new RewriteRegexRule();
    reverse.setRegex("/reverse/([^/]*)/(.*)");
    reverse.setReplacement("/reverse/$2/$1");
    rewrite.addRule(reverse);
     
    server.setHandler(rewrite);

    Rules

    有几种不同类型的rules。

    PatternRule

    用servlet模式语法匹配请求的URI。

    CookiePatternRule

    添加一个cookie到响应。

    HeaderPatternRule

    添加/改动响应中的header。

    RedirectPatternRule

    重定向响应。

    ResponsePatternRule

    发送响应码(status或者error)。

    RewritePatternRule

    重写URI。

    RegexRule

    用正則表達式匹配请求URI。

    RedirectRegexRule

    重定向响应。

    RewriteRegexRule

    重写URI

    HeaderRule

    匹配请求headers。

    匹配或者在一个header名称+特定的值,或者在一个header的存在(加不论什么值)。

    ForwardedSchemaHeaderRule

    设置请求的计划(scheme)(默认是https)。

    其他

    其他较为古怪的规则。

    MsieSslRule

    对IE5和IE6禁用为SSL保持活跃。

    LegacyRule

    实现RewriteHandler的遗留API。

    RuleContainer

    将rules组织在一起。

    VirtualHostRuleContainer

    包括的rules仅应用到一个特定的虚拟主机或者一套虚拟主机。

    写自己定义的handlers

    handler是处理请求的Jetty组件。
    一些Jetty用户从不须要写Jetty handler,而是使用Servlet API(http://download.eclipse.org/jetty/stable-9/xref/org/eclipse/jetty/servlet/package-summary.html)。你能重用已经存在的Jetty handlers,为上下文、安全、sessions和servlets,不须要不论什么扩展。然而,一些用户可能有特殊的需求或者操心足迹问题而禁用完整的servlet API。为他们实现一个Jetty handler是一种直截了当的方法,用最小的修改提供动态web内容。

    Handler API

    Handler接口提供了Jetty内容产生和处理的核心。实现这个接口的类被用于协调请求、过滤请求和产生内容。
    Handler接口的核心API是:

    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException

    这种方法的实现能处理一个请求、传递请求到还有一个handler(或servlet)、或者它能改动和/或包装请求,然后传递它。存在三种类型的handler:
     1)协调Handlers:传递请求到其他handlers(HandlerCollection、ContextHandlerCollection);
     2)过滤Handlers:放大一个请求,然后传递它到其他handlers(HandlerWrapper, ContextHandler, SessionHandler);
     3)产生Handlers:产生内容(ResourceHandler和ServletHandler)。

    目标

    一个handler的目标是处理请求的资源的标识符。这一般是来自一个HTTP请求的URI。然而,在以下两种环境下目标能够不同于请求的URI:
     1)假设请求被分发到一个命令的资源。比如一个命名的servlet。目标是那个资源的名称。
     2)假设请求是通过请求调度程序。目标是包括的资源的URI。不同于真正请求的URI。

    请求和响应

    处理方法的签名中使用的请求和响应对象是Servlet Request和Servlet Response。这些是标准的API。

    更常常的是,进入这些类的Jetty实现被要求:RequestResponse

    然而,因为请求和响应能够被handlers、filters和servlets包装,直接地传递实现是不可能的。以下的方法用于获取不论什么包装器下的核心实现对象:

    Request base_request = request instanceof Request ? (Request)request : HttpConnection.getCurrentConnection().getRequest();
    Response base_response = response instanceof Response ?

    (Response)response : HttpConnection.getCurrentConnection().getResponse();

    注意假设handler传递请求到还有一个handler。他应该用request/response对象传递,不使用基础对象。这是为了保留被上游handlers做的封装。

    分发

    分发參数展示了调用处理的状态,能够为:
     1)REQUEST == 1:从一个连接器收到的原始请求;
     2)FORWARD == 2:被一个RequestDispatcher前转的请求;
     3)INCLUDE == 4:被一个RequestDispatcher包含的请求;
     4)ERROR == 8:被容器前转到一个error handler的请求。


    这些对大部分的servlet和相关的handlers都是有意思的。比如,安全handler仅对REQUEST分发应用认证和授权。

    处理请求

    一个Handler能够处理一个请求通过:
     1)产生一个响应;
     2)过滤请求和/或响应;
     3)传递请求和响应到还有一个Handler。


    以下详细讲述。

    产生一个响应

    OneHandler展示了怎么产生一个响应。

    你能用通常的servlet响应API。通常将设置一些状态、内容headers、然后输出内容:

    response.setContentType("text/html");
    response.setStatus(HttpServletResponse.SC_OK);
    response.getWriter().println("<h1>Hello OneHandler</h1>");

    handler须要标注它完毕了对请求的处理,请求不应该被传递到其他handlers了:

    Request base_request = (request instanceof Request) ? (Request)request:HttpConnection.getCurrentConnection().getRequest();
    base_request.setHandled(true);

    过滤请求和/或响应

    一旦基础请求或响应对象被获取。你就能改动它。

    一般你将做改动以完毕:
     1)拆分URI到contextPath、servletPath和pathInfo组件;
     2)为静态内容将请求和资源相关联;
     3)将请求和session相关联;
     4)将请求和安全主体相关联;
     5)在请求分发到还有一个资源期间改变URI和路径。
    你也能更新请求的上下文:
     1)设置当前线程上下文类载入器;
     2)设置线程局部变量来表示当前ServletContext。
    通常Jetty传递一个已改动的请求到还有一个handler。并在finally块仅仅可以还原改动:

    try
    {
       base_request.setSession(a_session);
       next_handler.handle(target,request,response,dispatch);
    }
    finally
    {
       base_request.setSession(old_session);
    }

    实现HandlerWrapper类的类是典型的这样的类型的handler过滤器。

    传递请求和响应到还有一个Handler

    一个Handler能够简单的视察请求,然后使用目标、请求URI或其他信息以选择还有一个Handler作为下一个处理请求的Handler。这些handlers通常实现HandlerContainer接口。


    样例包含:

    Class Handler Collection

    HandlerList

    ContextHandlerCollection

    很多其它Handlers的信息

    Jetty Latest Source XRefJetty Latest JavaDoc获取每个Jetty Handler的具体信息。

    很多其它Jetty资料请看Jetty概观

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    Ajax学习笔记(1)
    html学习笔记(2)-字母大小写转换练习
    html学习笔记(1)--处理特殊字符以及其他的一些小细节
    jQuery学习笔记(8)--表格筛选
    jQuery学习笔记(7)--表格展开关闭
    Linux学习8-Linux常用命令(4)
    Linux学习7-Linux常用命令(3)
    Linux学习6-Linux常用命令(2)
    Linux学习6-Linux常用命令(1)
    Linux学习5-初学者注意事项
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4641255.html
Copyright © 2020-2023  润新知