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>这样子来访问也是可以被重写的。也就是相当于双向。