昨天开始webwork的复习,突然发现2.2.4(之前用2.1.7)的机制有些变化:
"一个初始的请求被发送到Servlet容器(如Tomcat或Resin),这个请求经过一个标准的Filter链,其中包括(可选的)ActionContextCleanUp Filter,如果你要在应用程序中整合其他的技术如SiteMesh,就需要使用这个这个Filter.然后请求经过 FilterDispatcher ... ...";
scud这样分析:
"在WebWork 2.2中,默认已经使用Filter的方式来进行对action的处理,这样做固然带来了很多好处,但是也有很多弊端.
当然,事情总是不断进步的,我们就要扬长避短了.
使用Filter方式带来的优点有:
可以服务静态内容(当然后来webwork也提供了方式来避免服务静态内容,因为对于普通文件应用服务器一般不比普通web服务器性能好)
可以处理多种请求,当然目前也没有更多的请求处理
缺点有:
在Servlet 2.3中,不能使用jsp:include或者ww:include包含action输出的结果了(因为Servlet容器不支持请求分发器转向到filter的映射)一个请求如果发生了Forward,一般不会再经过Filter了(include同理,这是前面一条的原因)
由于Servlet和Filter的不同,还会有很多其他问题--不过目前还没有注意到
首先我们来看看如何配置Filter
配置WebWork的Filter
在最简单的情况下,webwork 2.2.的web.xml是这样的:
<filter>
<filter-name>webwork</filter-name>
<filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>webwork</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
如果使用了SiteMesh,那么是这样配置的:
<filter>
<filter-name>webwork-cleanup</filter-name>
<filter-class>com.opensymphony.webwork.dispatcher.ActionContextCleanUp</filter-class>
</filter>
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
</filter>
<filter>
<filter-name>webwork</filter-name>
<filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>webwork-cleanup</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>webwork</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
注意中间是使用jsp时的配置,如果使用FreeMarker,要换成对应的PageFilter. (WebWork提供了FreeMarkerPageFilter和VelocityPageFilter)
分析Servlet 规范
Filter在Servlet 2.3规范中出现,配置方式就和最简单的webwork的配置相同,在Servlet 2.4中,对mapping做了改进,可以设置Filter服务于何种请求.举例如下:
<filter-mapping>
<filter-name>webwork</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
也就是说,Filter通过配置可以服务FORWARD和INCLUDE(以及ERROR)方式的请求了,而在Servlet 2.3中,是没有规定的.而在Servlet 2.4中,如果没有设置dispatcher,默认情况下是仅服务REQUEST类型的请求. 我觉得在Servlet 2.3的情况下,Filter也应该仅服务于REQUEST请求.(在Tomcat 下,本人测试确实如此,其他环境没有测试)
通过上述分析,我们可以看到,如果应用服务器支持Servlet 2.4,通过设置我们的web.xml为2.4的格式,然后设置Filter的服务类型,则可以对FORWARD,INCLUDE,ERROR类型的请求进行服务.
通过Servlet 2.4规范我们可以避免一些使用Filter的缺点,当然如果设置不当,可能也会带来一些毛病:
如果sitemesh映射处理不好,可能一个页面被多次装饰,所以要注意装饰设置和Filter设置的合理搭配
多次经过Filter,可能会造成混乱,以及性能问题
Include 一个Action
前面我们说过,升级到webwork 2.2后,文档上已经说使用ww:action的调用来替换ww:include和jsp:include对一个action的包含,当然我也是推荐ww:action来替换老的方式的. 但是这不等于说ww:include,jsp:include不能包含一个action了.
通过对filter-mapping的dispatcher的设置,可以完全使用包含action.
<filter-mapping>
<filter-name>webwork</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
注意如果有其他相关的Filter,也要进行类似配置,例如webwork-cleanup.
警告:我们不推荐使用这种方式!
URL Rewrite Filter的使用
url rewrite filter是一个java编写的优秀的重写url引擎.用于在java应用中重写URL. 当然如果你有web服务器的重写权限(例如apache),最好使用web服务器的ReWrite引擎,它们的效率会高于Url Rewrite Filter.
在WebWork 2.1.7的时候,因为WebWork使用Servlet处理请求,所以不对Filter造成不良影响,在WebWork 2.1.7中使用的配置如下:
<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>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/someurl/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>webwork</servlet-name>
<servlet-class>com.opensymphony.webwork.dispatcher.ServletDispatcher</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>webwork</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
而升级到webwork 2.2.2中时,由于webwork的配置改变了,对webwork的action的forward方式的重写就会无法生效了. ---如果你的rewrite全部都是redirect,则无须修改
(如果使用了forward重写方式,会发生404错误)
在Servlet 2.3规范的应用服务器中,这可能是个无法解决的问题!(也许能通过修改某些程序的代码可以做到)
如果你的应用服务器支持Servlet 2.4,则可以按照上面的说明修改web.xml,就可以继续使用了. (但是要避免前面说的多次filter的问题)
配置示例如下:
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<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>
<filter-name>webwork-cleanup</filter-name>
<filter-class>com.opensymphony.webwork.dispatcher.ActionContextCleanUp</filter-class>
</filter>
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
</filter>
<filter>
<filter-name>webwork</filter-name>
<filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/srun/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>webwork-cleanup</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>webwork</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
注意sitemesh的filter的配置,你的可能和此处不同,因为我要避免页面多次被装饰.当然可以通过sitemesh的配置文件,设置只装饰某个处理中的url即可. 也就是说,某种情况下,有可能你的sitemesh的filter-mapping中也要包括dispatcher的配置.
总之,要根据实际情况编写自己的web.xml."
继续学习中 ... ...
original text