注:本文档基本3.2.0版本。原文请参阅:http://tuckey.org/urlrewrite/manual/3.2/index.html
手册
社区支持请访问: urlrewrite谷歌小组 。
阅读 使用示例 和 ant任务 报告。如果你有任何找反馈,或者你想分享给大家的配置,可以 邮件我们 ,如果有任何建议和使用示例,请将它们提交到 urlrewrite谷歌小组论坛 。
安装
- 下载zip(或tar.gz)并将解压到你的上下文目录中,比如把urlrewrite.xml放到WEB-INF目录下。
- 把下面的代码添加到WEB-INF/web.xml中(尽量放置到servlet配置的上方)(详见过滤器参数部分)
<filter> <filter-name>UrlRewriteFilter</filter-name> <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class> </filter> <filter-mapping> <filter-name>UrlRewriteFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping>
- 把你的配置添加到WEB-INF/urlrewrite.xml中
- 重启服务。
你可以访问 http://127.0.0.1:8080/rewrite-status 查看配置输出。
过滤器参数(Filter Parameters)
下面列出了一些高级选项,如重新加载配置等。各个选项都有解释。
<?xml version="1.0" encoding="UTF-8"?>
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter
</filter-class>
<!-- 设置配置文件重新加载的间隔时间,以秒计,必须是一个合法的整数(0表示每次修改都检查,-1表示不做重新加载检查,默认为-1) -->
<!-- 源码中默认值为0 -->
<init-param>
<param-name>confReloadCheckInterval</param-name>
<param-value>60</param-value>
</init-param>
<!-- 如果需要求给配置文件的路径,可以通过confPath参数,路径相对于上下文跟目录(默认为/WEB-INF/urlrewrite.xml) -->
<init-param>
<param-name>confPath</param-name>
<param-value>/WEB-INF/urlrewrite.xml</param-value>
</init-param>
<!-- 设置日志级别,可选值为 TRACE, DEBUG, INFO(默认), WARN, ERROR, FATAL; 日志系统可选 log4j,
commons, slf4j; -->
<init-param>
<param-name>logLevel</param-name>
<param-value>DEBUG</param-value>
</init-param>
<!-- 你可以修改urlrewrite状态数据的目录,以便它不与你已部署的应用相冲突(注:默认为/rewrite-status) ,注:必须以/开头 -->
<init-param>
<param-name>statusPath</param-name>
<param-value>/status</param-value>
</init-param>
<!-- 可以禁用状态页面,可选值为true/false,(默认为true) -->
<init-param>
<param-name>statusEnabled</param-name>
<param-value>true</param-value>
</init-param>
<!-- 你可能想允许其他的host也可以看到状态页,可以用statusEnabledOnHosts参数来配置,值为,隔开的host列表,可使用*号通配符(默认为"localhost,
local, 127.0.0.1") -->
<init-param>
<param-name>statusEnabledOnHosts</param-name>
<param-value>localhost, dev.*.myco.com, *.uat.mycom.com
</param-value>
</init-param>
<!-- 默认false. 使用mod_rewrite风格的配置文件(若设置为true,则confPath没有被指定时会会设置为/WEB-INF/.htaccess) -->
<init-param>
<param-name>modRewriteConf</param-name>
<param-value>false</param-value>
</init-param>
<!-- 从参数modRewriteConfText中加载mod_rewrite风格的配置信息,注:如果调协这了个参数,其他的默认参数将被忽略
<init-param>
<param-name>modRewriteConfText</param-name>
<param-value>
RewriteRule ^/~([^/]+)/?(.*) /u/$1/$2 [R]
RewriteRule ^/([uge])/([^/]+)$ /$1/$2/ [R]
</param-value>
</init-param>
-->
<!-- 默认为false, 允许通过访问下面的url设置使用哪个配置文件/rewrite-status/?conf=/WEB-INF/urlrewrite2.xml。仅为测试方便而设计
<init-param>
<param-name>allowConfSwapViaHttp</param-name>
<param-value>false</param-value>
</init-param>
-->
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
注:设置logLevel为log4j或者commons将导致日志构建时调用log4j或commons-loggin类库。因此,需要把相关jar引入到classpath中。
配置文件 WEB-INF/urlrewrite.xml
一个简单的配置文件如下所示,把它放置到WEB-INF下面,并命名为urlrewrite.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN"
"http://www.tuckey.org/res/dtds/urlrewrite3.2.dtd">
<urlrewrite>
<rule>
<from>^/some/olddir/(.*)$</from>
<to type="redirect">/very/newdir/$1</to>
</rule>
<rule match-type="wildcard">
<from>/blog/archive/**</from>
<to type="redirect">/roller/history/$1</to>
</rule>
</urlrewrite>
urlrewrite.xml文件必须名为"urlrewrite.xml"的根节点,并且必须有至少一个rule元素。
rule节点必须包含一个from和一个to,可以有0或多个condition元素,并且可以有0或多个set元素。
当一个rule处理进来的请求时,所有的condition都会被执行,然后from将尝试与请求URL进行匹配,由to和from指定模式生成最终的URL,只要该rule匹配上了,set即会被执行。
当执行rule时,过滤器将会对所有的rule进行一个非常简单的循环,对每个rule执行如下伪代码所未的动作
Pattern.compile(<from> element);
pattern.matcher(request url);
matcher.replaceAll(<to> element);
if ( <condition> elements match && matcher.find() ) {
handle <set> elements (if any)
execute <run> elements (if any)
perform <to> element (if any)
}
3.1 <urlrewrite>元素
顶级元素。
属性 | 取值 | 解释 |
default-match-type(可选) | regex(默认) | 所有的rule和condition都会使用Java正则表达式引擎(除非在某个rule上指定了match-type) |
wildcard | 所有的rule和condition都会使用通配符表达式引擎(除非在某个rule上指定了match-type ) | |
decode-using(可选) | header,utf-8(默认) | 如果URL解码时将使用request.getCharacterEncoding(),如果返回值为空,则使用UTF-8 |
null | 不解码 | |
header | 只使用request.getCharacterEncoding()解码 | |
[encoding] | 仅使用指定编码去解码,如ISO-8859-1。到 Java Charset Object 查看所有的编码。 | |
header,[encoding] | 当URL解码时使用request.getCharacterEncoding() 解码,如果为空,使用指定的编码去解码。 | |
use-query-string(可选) | false(默认) | 查询参数不使会加到from中的url上。 |
true | 查看参数添加到from的url上。 | |
use-context(可选) | false(默认) | 上下文路径不会被添加到from的url上。 |
true | 上面文件路径会被添加到from的url上。 |
3.2 <rule>元素
零个或多个,规则的基础组件。
属性 | 取值 | 解释 |
enabled(可选) | true(默认) | 启用该规则 |
false | 禁用该规则 | |
match-type(可选) | regex(默认) | 该rule和condition都会使用Java正则表达式引擎 |
wildcard | 该rule和condition使用通配符表达式引擎 |
下面的示例,请求/world/usa/nyc会被分发到/world.jsp上
<rule match-type="regex">
<from>^/world/([a-z]+)/([a-z]+)$</from>
<to>/world.jsp</to>
</rule>
<rule match-type="wildcard">
<from>/world/*/*</from>
<to>/world.jsp</to>
</rule>
3.3 <outbound-rule> 元素
零或多个。相对于通用的规则来说,这个很简单,只是它通过response.encodeURL()用来重写url。
属性 | 取值 | 解释 |
enabled(可选) | true(默认) | 启用该规则 |
false | 禁用该规则 | |
encodefirst(可选) | false (默认) | 运行该规则后,执行encodeURL |
true | 运行该规则之前,执行encodeURL |
可以包含 run、from、to 和 set元素,例如:
<outbound-rule>
<from>^/world.jsp?country=([a-z]+)&city=([a-z]+)$</from>
<to>/world/$1/$2</to>
</outbound-rule>
使用上面的示例,下面的jsp代码:
<a href="<%= response.encodeURL("/world.jsp?country=usa&city=nyc") %>">nyc</a>
将会输出为:
<a href="/world/usa/nyc">nyc</a>
或者使用JSTL标签
<a href="<c:url value="/world.jsp?country=${country}&city=${city}" />">nyc</a>
将会输出为:
<a href="/world/usa/nyc">nyc</a>
注:如果使用JSTL,也好使。
3.4 <name> 元素
这也是一个可选元素,用于标识规则的名称。可以用于rule和outbound-rule。
<rule>
<name>World Rule</name>
<from>^/world/([a-z]+)/([a-z]+)$</from>
<to>/world.jsp?country=$1&city=$2</to>
</rule>
3.5 <note>元素
这个简单的可选元素,用于描述某个规则。可用于rule和outbound-rule。
<rule>
<name>World Rule</name>
<note>
Cleanly redirect world requests to JSP,
a country and city must be specified.
</note>
<from>^/world/([a-z]+)/([a-z]+)$</from>
<to>/world.jsp</to>
</rule>
3.6 <condition>元素
提供给你为某个规则选择条件的元素。规则的所有条件必须都必须被满足(除非or上显示设置了next)。取值可以是正则表达式。
属性 | 取值 | 解释 |
类型(可选) | header(默认) | 如果选择这个类型,头名称必须用name属性来指定 |
method | 请求的方式,如GET、POST、HEAD等 | |
port | 正在运行的web应用服务的端口 | |
time | 服务端的当前 时间。(取值为自1970-01-01 00:00:00开始的秒数,或者unix时间),即(new Date().getTime())。这可能用于确定内容只在你设置的时间点生效。 | |
year | 服务器当前年份。即 (Calendar.getInstance()).get(Calendar.YEAR) | |
month | 服务器当前月份。一月是0。即(Calendar.getInstance()).get(Calendar.MONTH) | |
dayofmonth | 服务器一月中的第几天。3月份第一天是1.即 | |
dayofweek | 服务器周的第几天。周六是1,周日是7。即 | |
ampm | 服务器端上午还是下午,即 | |
hourofday | 服务器端一天中的第几小时(24小时制),下午10点是22,即 | |
minute | 服务端当前时间的分钟字段,即 | |
second | 服务端当前时间的秒钟字段,即 | |
millisecond | 服务端当前时间的毫秒字段,即 (Calendar.getInstance()).get(Calendar.MILLISECOND) | |
attribute | 将会检查request中arttribute中的值,(不要与parameter混淆),当使用该类型时,name必须设置。 即request.getAttribute([name]) | |
auth-type | 将检查request的验证类型,即:request.getAuthType() | |
character-encoding | 当前请求的字符编码,即 request.getCharacterEncoding() | |
content-length | 请求的内容长度(可以让你拒绝大请求),即request.getContentLength() | |
content-type | 请求的内容类型(可能不是很有用),即:request.getContentType() | |
context-path | 请求的上下文路径,即:request.getContextPath() | |
cookie | cookie的值,注:用该类型时name必须指定。即
| |
parameter | 一个检查查询参数的更条理的方式,这将检查GET或POST请求的参数,注:name必须指定。即:request.getParameter([name]) | |
path-info | 即:request.getPathInfo() | |
path-translated | 即:request.getPathTranslated() | |
protocol | 请求的协议,如HTTP/1.1。即:request.getProtocol() | |
query-string | 组成当前请求的查询参数,如id=2345&name=bob,即:request.getQueryString() | |
remote-addr | 组成当前请求的客户端IP地址,如123.123.123.123,即:getRemoteAddr() | |
remote-host | 组成当前请求的远程主机名,如123qwdsl.att.com(注:这仅在你的应用服务器配置了获取主机名时才有效,多数没有配置)。即:request.getRemoteHost() | |
remote-user | 如果用户已通过验证,该值表示请求的登录用户,即:request.getRemoteUser() | |
requested-session-id | 返回由客户端指定的会话ID,如:2344asd234sada4 。即:request.getRequestedSessionId() | |
requested-session-id-from-cookie | sessionID是否来自于cookie,即:request.isRequestedSessionIdFromCookie() | |
requested-session-id-from-url | cookie是否来自来URL,即:isRequestedSessionIdFromURL() | |
requested-session-id-valid | cookie是否有效。即:request.isRequestedSessionIdValid() | |
request-uri | 返回请求url从协议名到查询参数的一部分,HTTP请求的第一行。即:request.getRequestURI() | |
request-url | 重建客户端请求的URL,返回的URL包含了协议、服务名、端口和路径,但不包吃住查询参数。即:request.getRequestURL() | |
session-attribute | (注:name必须设置),即:session.getAttribute([name]) | |
session-isnew | 会话是否是新的。即:session.isNew() | |
server-name | 服务端的主机名,哪个请求被发送(来自于主机header而不是机器名),即request.getServerName(). | |
scheme | 请求使用的scheme,如http或https。 即:request.getScheme()
| |
user-in-role | 该值不能是正则表达式。 即:request.isInRole([value])
| |
name(可选) | 可以任何值 | 如果type是header,则该项用给定了name的http请求头与运行值比较。 |
next(可选) | and(默认) | 下一个规则与该规则都匹配 |
or | 下一个规则或这个条件任一个匹配 | |
operator(可选) | equal(默认) | 相等,表示正则表达式匹配或值相等 |
notequal | 不等于,注:只有数值型都有效 | |
greater | 大于,注:只有数值型都有效 | |
less | 小于,注:只有数值型都有效 | |
greaterorequal | 大于或等于,注:只有数值型才有效 | |
lessorequal | 小于或等于,注:只有数值型才有效 |
示例:
<condition name="user-agent" operator="notequal">Mozilla/[1-4]</condition>
<condition type="user-in-role" operator="notequal">bigboss</condition>
<condition name="host" operator="notequal">www.example.com</condition>
<condition type="method" next="or">PROPFIND</condition>
<condition type="method">PUT</condition>
3.7 <from>元素
每个rule或outbound-rule都必须有from元素。取可以是个正则表达式,注:from的url是相对上下文路径。
属性 | 取值 | 解释 |
casesensitive(可选) | false(默认) | 大小写不敏感 |
true | 大小写敏感 |
示例:
<from>^/world/([a-z]+)$</from>
3.8 <to>元素
值可以是正则替换表达式。
属性 | 取值 | 解释 |
type(可选) | forward(默认) | 如果请求匹配了rule上的conditions,则from上指定的url将内部跳转至to元素指定的url上,注:to上的url的上下文必须与from的相同。与下面的代码效果相同: RequestDispatcher rq = request.getRequestDispatcher([to value]); |
passthrough | 与forward相同 | |
redirect | 请求匹配上了condition,则from的url将重定向至to指定的url。与下面的代码效果相同: HttpServletResponse.sendRedirect([to value])) | |
permanent-redirect | 与下面代码相同: response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); (注:SC_MOVED_PERMANENTLY是HTTP状态码,值为301) | |
temporay-redirect | 与下面代码相同: response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); (注: SC_MOVED_TEMPORARILY是HTTP状态码,值为302) | |
pre-include | ||
post-include | ||
proxy | 请求将被代理到指定的完整url上,当使用该特性时,必须把common-http和commons-codec放到类路径当中。 | |
last(可选) | false(默认) | 如果这个rule成功,则剩余的rule也会被处理。 |
true | 如果这个rule匹配上,则剩余的rule不再处理了。 | |
encode(可选) | false(在rule中为默认) | response.encodeURL([to])不会被执行 |
true(在outbound-rule中为默认) | 在to元素指定的url进行重定向之前,执行response.encodeURL([to]) | |
context(可选) | 如果应用服务端配置了允许“cross context”通讯,则该属性可以用于forward(仅仅是forward,而不是重定向或其的to类型)请求到一个指定名称的servlet上下文。 在Tomcat中,对一个实例,应用上下文在服务项配置(server.xml或context.xml)需要一个可选项crossContext="true"。对实例,前面提到的两个应用要定义成下面的样式: <Context docBase="app" path="/app" reloadable="true" crossContext="true"/> <Context docBase="forum" path="/forum" reloadable="true" crossContext="true"/> |
注:"to"元素的值可以为null,例如<to>null</to>,意思是如果该rule匹配后,请求不会继续往后走了,即该fileter将不调用chain.doFilter。
如果"to"元素被设置为-,则没有适当的url被替换,请求还会像原生一样,就像没发生任何事一样。即该filter将调用chain.doFilter