UrlRewrite
UrlRewrite就是我们通常说的地址重写,用户得到的全部都是经过处理后的URL地址。
UrlRewrite优点
(1)提高安全性
可以有效的避免一些参数名、ID等完全暴露在用户面前,如果用户随便乱输的话,不符合规则的话直接会返回个404或错误页面,
这比直接返回500或一大堆服务器错误信息要好的多。
(2)美化URL
去除了那些比如*.do之类的后缀名、长长的参数串等,可以自己组织精简更能反映访问模块内容的URL
(3)利于搜索引擎的收入
通过对URL的一些优化,可以使搜索引擎更好的识别与收录网站的信息
UrlRewrite实例
实例应用版本urlrewritefilter-4.0.3. Tomcat服务器端口定制为80
1. 创建web项目,增加 urlrewritefilter-4.0.3.jar 到 WEB-INF/lib
如果是maven项目,添加如下坐标
<dependency>
<groupId>org.tuckey</groupId>
<artifactId>urlrewritefilter</artifactId>
<version>4.0.3</version>
</dependency>
2. 在WEB-INF/web.xml 增加urlrewritefilter过滤器 (放在过滤器的第一位)
<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>
3. 配置urlrewrite.xml
添加urlrewrite.xml 到工程的WEB-INF目录下
- 官方说明
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN"
"http://tuckey.org/res/dtds/urlrewrite3.3.dtd">
<urlrewrite use-query-string="true">
<!--使用rule是对用户输入的url进行处理-->
<rule>
<note>
The rule means that requests to /test/status/ will be redirected to
/rewrite-status
the url will be rewritten.
</note>
<from>/test/status/</from>
<to type="redirect">%{context-path}/rewrite-status</to>
</rule>
<!--使用outbound-rule对页面中的网址也进行重写-->
<outbound-rule>
<note>
The outbound-rule specifies that when response.encodeURL is called (if
you are using JSTL c:url)
the url /rewrite-status will be rewritten to /test/status/.
The above rule and this outbound-rule means that end users should never
see the
url /rewrite-status only /test/status/ both in thier location bar and in
hyperlinks
in your pages.
</note>
<from>/rewrite-status</from>
<to>/test/status/</to>
</outbound-rule>
</urlrewrite>
urlrewrite是个过虑器,它将会过虑用户的所有请求,符合规则的便对其进行重定向。
rule 是urlrewrite下的子节点,是urlrewrite的主要规则节点,在它里面包含from 和to两个子节点,from表示请求的URL,to表示将转到的真实的URL。
rule结点中from的规则默认使用的是正则表达式来匹配的,
当用户访问服务器时的URL会与该配置相比较,如果符合规则就会按照下面to结点中的配置对其进行跳转,其默认是forward跳转。
使用rule是对用户输入的url进行处理
1、使用正则表达式匹配(rule 的默认匹配方式是正则表达式)
- 没有参数
<rule>
<from>^/demo/(\w+).html$</from>//客户端访问的地址:http://127.0.0.1:8080/Struts/demo/hello.html
<to type="redirect">/Struts/$1</to>//实际访问的地址:http://127.0.0.1:8080/Struts/hello
</rule>
- 有参数
<rule>
<from>^/demo1/(\w+)/(\w+).html$</from>
<to type="redirect" >/Struts/$1.action?age=$2</to>
</rule>
2、使用通配符匹配
- 转发模式:forward方式跳转
<rule match-type="wildcard">
<from>/demo2/*/*</from>
<to type="forward>/Struts/$1.action?age=$2</to>
</rule>
-
重定向模式:redirect方式跳转
<rule match-type="wildcard">
<from>/demo2/*/*</from>
<to type="redirect">/Struts/$1.action?age=$2</to>
</rule>
3. 除了支持指定规则的跳转外,UrlRewrite还支持当匹配规则的时候执行某个对象的某个函数
示例:
要求urlrewrite.xml引入urlrewrite3.3.dtd及以上
<rule>
<from>^/demo3/(\w+)/(\w+).html$</from>
<run class="com.sean.action.Demo" method="log" />//匹配规则后,指定的函数只在第一次匹配成功的时候执行
<class-rule class="com.sean.action.Demo" method="log2"/>//每次匹配规则后,指定的函数都会执行一次
<to type="redirect" >/Struts/$1.action?age=$2</to>
</rule>
如上述设置,要实现匹配规则是执行某个函数,需要添加多一个run节点,在节点上面添加对应的类属性和方法属性。 同时,对应的类必须继承RewriteRule类,执行的方法必须传入两个参数,分别是HttpServletRequest 和HttpServletResponse
//记得要继承RewriteRule类
public class Demo extends RewriteRule{
public void log(HttpServletRequest request,HttpServletResponse response){
System.out.println("haha1");
}
public void log2(HttpServletRequest request,HttpServletResponse response){
System.out.println("haha2");
}
}
使用outbound-rule对页面中的网址也进行重写
<outbound-rule match-type="regex">
<from>/(\w+).action\?id=(\w+)$</from>
<to>/$1.html</to>
</outbound-rule>
在UrlRewrite中添加该规则后,我们在页面中原本的地址是:
<a href="<c:url balue='/demo.action>id=111' />"> 测试</a>
可是在页面中显示却成了如下:
<a href="/Struts/demo.html">测试</a>
这样可以隐藏了许多开发中的技术,较为安全。
这其中有点是需要注意的,引用官网中的一段话:
Using the example above JSP's with the code
<a href="<%= response.encodeURL("/world.jsp?country=usa&city=nyc") %>">nyc</a>
will output
<a href="/world/usa/nyc">nyc</a>
Or JSTL
<a href="<c:url value="/world.jsp?country=${country}&city=${city}" />">nyc</a>
will output
<a href="/world/usa/nyc">nyc</a>
注意:<rule>标签可以单独的存在。
而<outbound-rule>必须要和<rule>标签成对出现。而且在页面的时候需要<c:url>标签来转换成<rule>所对应的规则。
<urlrewrite>
<rule>
<from>/servelt/detail/([0-9]+)_([0-9]+).html</from>
<to>/servelt/detail?magid=$1&categoryId=$2</to>
</rule>
<outbound-rule>
<from>/servlet/detail\?magid=([0-9]+)&categoryId=([0-9]+)</from>
<to>/servlet/detail/$1_$2.html</to>
</outbound-rule>
</urlrewrite>
通过上面的配置基本上实现了上面的提出的问题。
1:通过:“/servlet/detail?magid=24&categoryid=42”来访问,得在<outbound-rule>标签中配置,同时还得在<rule>中配置相关信息。如果rule中没有配置,会找不到相关的资源信息,抱404错误
2:上面的配置文件得注意的地方:在<outbound-rule>中的特殊符号“?”“&”等得转义。不然的话也会出错,不能被重写。像上面的“outbound-rule>from标签中路径中如果出现“?”问号的话,记得要转义,“\?”。
3:jsp中,上面提出的问题中,在页面如果直接写<a href="/servlet/detail?magid=24&categoryid=42"/>这样也是错误的,同样也没办法被重写。
它只能用在response.encodeURL() 或者jstl中c:url中,才会被重写。这个也是容易犯错的地方。
jsp:页面关键代码:
<a href="<c:url value='/servlet/detail?magid=3934&categoryId=3'/>">JSTl c:URL</a><hr/>
<a href="<%=response.encodeUrl("/servlet/detail?magid=3934&categoryId=3") %>">response EncodeURL</a>
4:如果想在<outbound-rule>中定义多个from to标签这个是不可以的,<outbound-rule>中只能定义一个from to 标签。这个是我在程序中测试得出来的结论。只能定义一对from to标签是在个人测试得出来的结论,如果您测试出来不是这样的话,请给我指正,评判。
5:通过上面的urlrewrite.xml的配置, <a href=”servlet/detail?44_77.html">测试</a>这样子来访问也是可以被重写的。也就是相当于双向。