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总览

时间: 2024-08-07 00:05:52

Jetty开发指导:Handlers的相关文章

Jetty开发指导:Maven和Jetty

使用Maven Apache Maven是一种软件项目管理和综合工具.基于项目对象模型(POM)的概念,Maven能从核心信息管理一个项目的构建.报告和文档. 他是用于构建一个web应用项目的理想工具,这些项目能用jetty-maven-plugin轻松的运行web应用,从而节省开发时间.你也能用Maven构建.测试和运行一个嵌入Jetty的项目. 首先我们将看一个很简单嵌入Jetty的HelloWorld Java应用,然后看一个简单的webapp怎么使用jetty-maven-plugin加

Jetty开发指导:调试

如果你有一个web应用部署到Jetty,你能容易地从远程调试它.但首先你必须使用附加的参数启动远程JVM,然后在Eclipse中启动一个远程调试连接.这很容易就能做到. 注意:下面的例子假定你正在部署你的web应用到Jetty发布版本中. 设置Jetty调试端口 假定你将你的webapp部署到Jetty,有两种不同的方式设置调试端口: 通过命令行 在命令行中增加要求的参数如下: $ java -Xdebug -agentlib:jdwp=transport=dt_socket,address=9

Jetty:开发指导Handlers

Rewrite Handler RewriteHandler匹配一个基于该请求的规则集合,然后根据匹配规则的变更请求. 最常见的要求是改写URI.但不限于:规则可以被配置为重定向响应.设置cookie或响应码响应.变化header.等等. 高速開始 标准Jetty公布中包括jetty-rewrite模块JAR,在lib/jetty-rewrite-*.jar,和一个样例配置文件,在etc/jetty-rewrite.xml. 为了激活重写模块,用样例配置文件.用例如以下命令启动Jetty: $

Jetty开发指导:嵌入

Jetty嵌入的HelloWorld 这节提供一个指导展示你怎么使用Jetty API快速开发嵌入的代码. 下载Jars Jetty被分解到多个jars和依赖,方便你选择自己需要的最小jar集合.通常使用Maven是最好的,然而这里使用了一个聚集的jar,包含了所有的Jetty类.你能手动的下载聚集的jetty-all jar和servlet api jar,通过使用wget或者类似的命令(例如:curl)或者浏览器.用wget如下: mkdir Demo cd Demo wget -O jet

Jetty开发指导:框架

Spring设置 你能嵌入Jetty到你的项目中,也能够使用差点儿全部的IoC类型框架,包含Spring.假设全部你想做的是在你的Spring中设置Jetty Server,那么以下的xml片段能够作为一个样例.假设你想使用spring代替jetty-xml也是能够的,但这样将不能利用模块系统的其余部分. Jetty-Spring模块 一个Jetty Spring模块的框架能通过模块机制激活.比如: $ java -jar start.jar --add-to-startd=spring 这(或

Jetty开发指导:WebSocket介绍

WebSocket是一个新的基于HTTP的双向通讯的协议. 它是基于低级别的框架协议.使用UTF-8 TEXT或者BINARY格式传递信息. 在WebSocket中的单个信息能够是不论什么长度(然而底层框架有单帧63bits的限制). 发送的信息数量不受限制. 信息被持续的发送,基础协议不支持交叉的信息. 一个WebSocket连接经历一些主要的状态改变: 1)CONNECTING:HTTP升级到WebSocket正在进行中 2)OPEN:HTTP升级成功,而且socket如今打开并准备读/写

Jetty开发指导:HTTP Client

介绍 Jetty HTTP client模块提供易用的API.工具类和一个高性能.异步的实现来运行HTTP和HTTPS请求. Jetty HTTP client模块要求Java版本号1.7或者更高,Java 1.8的应用能用lambda表达式在一些HTTP client API中. Jetty HTTP client被实现和提供一个异步的API.不会由于I/O时间堵塞,因此使它在线程的利用上更有效率,并不是常适合用于负载測试和并行计算. 然而,有时你全部须要做的是对一个资源运行一个GET请求,H

Jetty开发指导:Jetty Websocket API

Jetty WebSocket API使用 Jetty提供了功能更强的WebSocket API,使用一个公共的核心API供WebSockets的服务端和client使用. 他是一个基于WebSocket消息的事件驱动的API. WebSocket事件 每一个WebSocket都能接收多种事件: On Connect Event 表示WebSocket升级成功,WebSocket如今打开. 你将收到一个org.eclipse.jetty.websocket.api.Session对象,相应这个O

Jetty使用教程(四:21-22)—Jetty开发指南

二十一.嵌入式开发 21.1 Jetty嵌入式开发HelloWorld 本章节将提供一些教程,通过Jetty API快速开发嵌入式代码 21.1.1 下载Jetty的jar包 Jetty目前已经把所有功能分解成小的jar包,用户可以根据需要选择合适的jar包,来实现需要的功能.通常建议用户使用maven等管理工具来管理jar包,然而本教程使用一个包含所有功能的合集jar包来演示,用户可以使用curl或者浏览器下载jetty-all.jar包. jetty-all.jar下载地址:http://c