WebWork 2 : TutorialLesson05
This page last changed on Sep 16, 2004 by vitorsouza.
第五课: 截取器(Interceptors)截取器可以将任意代码包含在调用栈中活动执行前或之后, 它可以极大的简化代码同时提供增强代码复用能力. XWork和WebWork的许多特性多作为截取器实现, 可以和你自己的拦截器一起通过外部配置任意指定顺序并配置在任意活动上.换言之, 当你访问一个*.action的地址, WebWork的 class="monospaced">ServletDispatcher执行一个活动调用. 在活动执行前, 这一调用可以被另一个对象截取, 这个对象就称为截取器. 要想在一个活动执行之前(或之后)设置一个截取器, 只需正确配置xwork.xml, 如下例所示, 借用自4.1.1: 4.1.1中的截取器配置:<action name="formProcessing" class="lesson04_01_01.FormProcessingAction"> <result name="input" type="dispatcher">ex01-index.jsp</result> <result name="success" type="dispatcher">ex01-success.jsp</result> <interceptor-ref name="validationWorkflowStack" /> </action> 如你所见, 4.1.1中的活动formProcessing使用了validationWorkflowStack. 它是一个截取器栈, 栈中按照截取器的执行顺序进行组织. 这个截取器栈定义在webwork-default.xml, 这样我们需要做的就是在活动配置的<interceptor-ref />或包配置中的<default-interceptor-ref />中声明, 就像第三课的第一个例一样: 3.1中的截取器配置:<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.0.dtd"> <xwork> <!-- Include webwork defaults (from WebWork JAR). --> <include file="webwork-default.xml" /> <!-- Configuration for the default package. --> <package name="default" extends="webwork-default"> <!-- Default interceptor stack. --> <default-interceptor-ref name="defaultStack" /> <!-- Action: Lesson 03: HelloWebWorldAction. --> <action name="helloWebWorld" class="lesson03.HelloWebWorldAction"> <result name="success" type="dispatcher">ex01-success.jsp</result> </action> </package> </xwork> 让我们先看看它是如何工作的:
深入观察webwork-default.xml我们可以发现这是怎样做到的: webwork-default.xml:<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.0.dtd"> <xwork> <package name="webwork-default"> <result-types> <result-type name="dispatcher" default="true" class="com.opensymphony.webwork.dispatcher.ServletDispatcherResult"/> <result-type name="redirect" class="com.opensymphony.webwork.dispatcher.ServletRedirectResult"/> <result-type name="velocity" class="com.opensymphony.webwork.dispatcher.VelocityResult"/> <result-type name="chain" class="com.opensymphony.xwork.ActionChainResult"/> <result-type name="xslt" class="com.opensymphony.webwork.views.xslt.XSLTResult"/> </result-types> <interceptors> <interceptor name="timer" class="com.opensymphony.xwork.interceptor.TimerInterceptor"/> <interceptor name="logger" class="com.opensymphony.xwork.interceptor.LoggingInterceptor"/> <interceptor name="chain" class="com.opensymphony.xwork.interceptor.ChainingInterceptor"/> <interceptor name="static-params" class="com.opensymphony.xwork.interceptor.StaticParametersInterceptor"/> <interceptor name="params" class="com.opensymphony.xwork.interceptor.ParametersInterceptor"/> <interceptor name="model-driven" class="com.opensymphony.xwork.interceptor.ModelDrivenInterceptor"/> <interceptor name="component" class="com.opensymphony.xwork.interceptor.component.ComponentInterceptor"/> <interceptor name="token" class="com.opensymphony.webwork.interceptor.TokenInterceptor"/> <interceptor name="token-session" class="com.opensymphony.webwork.interceptor.TokenSessionStoreInterceptor"/> <interceptor name="validation" class="com.opensymphony.xwork.validator.ValidationInterceptor"/> <interceptor name="workflow" class="com.opensymphony.xwork.interceptor.DefaultWorkflowInterceptor"/> <interceptor name="servlet-config" class="com.opensymphony.webwork.interceptor.ServletConfigInterceptor"/> <interceptor name="prepare" class="com.opensymphony.xwork.interceptor.PrepareInterceptor"/> <interceptor name="conversionError" class="com.opensymphony.webwork.interceptor.WebWorkConversionErrorInterceptor"/> <interceptor-stack name="defaultStack"> <interceptor-ref name="static-params"/> <interceptor-ref name="params"/> <interceptor-ref name="conversionError"/> </interceptor-stack> <interceptor-stack name="validationWorkflowStack"> <interceptor-ref name="defaultStack"/> <interceptor-ref name="validation"/> <interceptor-ref name="workflow"/> </interceptor-stack> </interceptors> </package> </xwork>
构建自己的截取器如果上述截取器都不符合你的特殊需要, 你需要实现自己的截取器. 幸运的是, 这是一个非常容易完成的任务. 假定我们需要一个截取器根据不同的时段(早晨, 下午或晚上)在session中放入对应的问候语. 下文展示了如何实现它:GreetingInterceptor.java:package lesson05; import java.util.Calendar; import com.opensymphony.xwork.interceptor.Interceptor; import com.opensymphony.xwork.ActionInvocation; public class GreetingInterceptor implements Interceptor { public void init() { } public void destroy() { } public String intercept(ActionInvocation invocation) throws Exception { Calendar calendar = Calendar.getInstance(); int hour = calendar.get(Calendar.HOUR_OF_DAY); String greeting = (hour < 6) ? "Good evening" : ((hour < 12) ? "Good morning": ((hour < 18) ? "Good afternoon": "Good evening")); invocation.getInvocationContext().getSession().put("greeting", greeting); String result = invocation.invoke(); return result; } } xwork.xml:<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.0.dtd"> <xwork> <!-- Include webwork defaults (from WebWork JAR). --> <include file="webwork-default.xml" /> <!-- Configuration for the default package. --> <package name="default" extends="webwork-default"> <interceptors> <interceptor name="greeting" class="section02.lesson05.GreetingInterceptor" /> </interceptors> <!-- Action: Lesson 5: GreetingInterceptor. --> <action name="greetingAction" class="lesson05.GreetingAction"> <result name="success" type="velocity">ex01-result.vm</result> <interceptor-ref name="greeting" /> </action> </package> </xwork> GreetingAction.java:package lesson05; import com.opensymphony.xwork.ActionSupport; public class GreetingAction extends ActionSupport { public String execute() throws Exception { return SUCCESS; } } ex01-result.vm:<html> <head> <title>WebWork Tutorial - Lesson 5 - Example 1</title> </head> <body> #set ($ses = $req.getSession()) <p><b>${ses.getAttribute('greeting')}!</b></p> </body> </html> 先来看一下截取器类. 和之前介绍的一样, 截取器必须实现com.opensymphony.xwork.interceptor.Interceptor的方法: init(), 将在初始化时被调用, destroy(), 在销毁时被调用, 最为重要, intercept(ActionInvocation invocation), 该方法是加入工作代码的地方. 注意, 我们的截取器返回invocation.invoke()的结果, 该方法将执行栈中下一个截取器, 如果本截取器是栈中的最后一个, 将执行活动. 这意味着截取器有短路(short-circuiting)活动调用的能力, 可以根本不执行活动直接返回一个String结果! 这种用法需要谨慎使用.截取器的另一个功能是在活动执行后执行代码. 为此, 只需将代码放在invocation.invoke()调用之后. WebWork提供一个已经实现下列行为的抽象类: com.opensymphony.xwork.interceptor.AroundInterceptor. 只须继承(extend)该类并实现方法before(ActionInvocation invocation)和after(ActionInvocation dispatcher, String result). xwork.xml中关于活动类和结果页面的配置内容简洁明了不需要进一步解释.试试这个例子! 上一课 | 指南结束 |
Document generated by Confluence on Dec 14, 2004 16:36 |