1. 在apache中配置
2. 用URLRewrite(详细:重点是UrlRewrite+Struts2)
1) 从http://tuckey.org/urlrewrite/ 下载最新的jar包下来,现时我用的是Url Rewrite3.2
2) 将urlrewrite.xml拷贝到WEB-INF目录下
3) 在web.xml中配置其拦截器。注意,拦截器应放在strutsFilter的前面。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
<init-param>
<param-name>logLevel</param-name>
<param-value>WARN</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST </dispatcher>
<dispatcher>FORWARD </dispatcher>
</filter-mapping>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.action</url-pattern>
<dispatcher>REQUEST </dispatcher>
<dispatcher>FORWARD </dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
</web-app>
其中,<dispatcher>REQUEST </dispatcher>和<dispatcher>FORWARD </dispatcher> 主要说明该拦截器拦截的请求包括客户端的请求和从服务器端forward的请求。在很多的网文中,都提到struts2的<url-pattern>/*</url-pattern> 我试过,这样是会报内存溢出异常的。上述的是2.16的版本的配置。
以下是urlrewrite.xml的配置
<rule>
<from>/test.dhtml</from>
<to type="forward">test.action</to>
</rule>
<rule>
<from>^/([a-zA-Z]+)/save/id/([a-zA-Z0-9]*).dhtml</from>
<to type="forward">$1!save.action?id=$2</to>
</rule>
<rule>
<from>^/([a-zA-z]+)/([a-zA-Z0-9]*).dhtml</from>
<to type="forward">%{context-path}/$1!$2.action</to>
</rule>
<rule>
<from>^/content/([a-zA-Z]+.*).html</from>
<to type="forward">/WEB-INF/content/login-error.jsp</to>
</rule>
之前如果在web.xml中设置<dispatcher>的话,则一直都不能forward都对应的action中去。以上 在地址栏中输入 http://lacalhost:8080/应用名/test.dhtml 就可以映射到test.action中。如果要映射test!save.action可以写成 test/save.dhtml就可以了。
看 test-access.jsp的代码(这里,我用了Convention的零配置,所以test-access.jsp在 WEB-INF/content目录中)
<s:form action="test/save.dhtml" method="POST">
<s:textfield name="msg" label="输入信息"/>
<s:token name="token"/>
<s:submit value="确定" />
</s:form>
这里加入了 token令牌,主要是防止表单重复提交的。
那么,我们可以将在@Result中的错误页面也可以写成html的形式了,因为在上面配置了。
<rule>
<from>^/content/([a-zA-Z]+.*).html</from>
<to type="forward">/WEB-INF/content/$1.jsp</to>
</rule>
将所有的html转换成.jsp来处理。
那么,在@Result中 我们就可以这样写:
@Result(name="invalid.token",location="/content/error.html",type="redirect")})
在重复提交的情况下,URL会转向到/WEB-INF/content/error.jsp中。
但是上述<s:form action="test/save.dhtml" method="POST">并不是一种好的方式。它在一定程度上依赖了UrlRewrite。我们希望,在<s:form/>中依然写test!save.action 但是在页面中显示的是test/save.dhtml。那么我们可以用<outBund-rule/>标签。
此标签的原理是,页面通过UrlRewrite过滤器后,这个过滤器会遍历这个页面,用设定的正则来替换页面中的URL。如:
<outbound-rule>
<from>/test!save.action</from>
<to type="redirect">/test/save.dhtml</to>
</outbound-rule>
这样,在jsp中写的<s:form action=”test!save.action”> 而通过编译后在客户端中的源码就可以看到:<form id="test" name="test" action="/strutsTest/test/save.dhtml" method="POST">
到此,还是不能进行映射,我们还要进行对test/save.dhtml进行<role/>映射。
<rule>
<from>^/test/save.dhtml</from>
<to type="forward">test!save.action</to>
</rule>
总结:UrlRewrite这种方式虽好,但是他在每次匹配一个页面的时候都会遍历urlrewrite.xml中的所有<role/> 所以,在用的时候,应该注意,尽量将<role/>的个数做到越少。那就需要尽量写出更通用的正则表达式。尽量让代码规范性。这也是高质量代码的要求。