WebWork2教程(中文版)(Interceptors)(http://www.chinaitpower.com/A/2002-04-14/19786.html)

本文详细介绍了WebWork框架中的拦截器机制,包括内置拦截器的功能介绍及如何创建自定义拦截器。

Interceptors允许在调用堆栈中包含任意在Action处理之前和/或处理之后执行的代码。这是你的代码简单,更能重用。XworkWebWork的大部分特性都是Interceptors实现的。你可以通过外部配置,按照你定义的顺序,对指定的Action应用你自己的Interceptors

当你访问.action URL时,WebWorkServletDispatcher启动Action对象,在Action被执行之前,启动允许被其它的对象中断,这就称Interceptor。在指定的Action之前(或之后)执行Interceptor,只要在xwork.xml中配置属性。下面是4.1.1节中展示UI标记用法的例子的Interceptor配置:

<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>

FormProcessingAction使用了validationWorkflowStack。这是一个Interceptor堆,组织一组按顺序执行的InterceptorsValidationWorkflowStackwebwork-default.xml中配置,所以我们只要使用<interceptor-ref />Action配置中,或使用<default-interceptor-ref />package配置中使用它。下面是HelloWebWorld例子的Interceptor配置:

<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" 
"http://www.opensymphony.com/xwork/xwork-1.0.dtd">
<xwork>
       <!-- Include webwork defaults (from WebWork-2.1 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>

看一下Interceptor如何工作的

l         创建Interceptor类,需要扩展com.opensymphony.xwork.interceptor.Interceptor接口(包含在xwork-1.0.jar);

l         xwork.xml文件中,使用<interceptors />内嵌的<interceptor />声明Interceptor类;

l         使用<interceptor-stack />创建Interceptor堆(可选);

l         使用<interceptor-ref /> <default-interceptor-ref />哪些Interceptor由哪个Action使用;前者由指定Action使用,后者为所有Action使用

1webwork-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>

既然在我们的xwork.xml中包含了webwork-default.xml,我们就可以在Action中使用这些InterceptorInterceptor堆。下面是这些Interceptor做的事情:

l         timer:对Action的执行进行计时(包括嵌套的Interceptor和视图)

l         chain:使前一个Action的属性对当前的Action有效,通常创建Action

l         static-params:设置xwork.xml中的参数到Action中(<action />内嵌的<param />

l         params:设置请求参数(POSTGET)到Action

l         model-driven:如果Action实现ModelDriven,将getModel()的结果推到Value Stack

l         component:使能和注册组件,使其对Action有效

l         token:检查Action中的有效token,防止重复提交

l         token-session:同上,但是当处理到无效token时,在session中保存提交的数据

l         validation:使用在{Action}-vaildation.xml中定义的验证器进行数据验证

l         workflow:调用Action类中的validate()方法,在发生错误时,返回INPUT视图;应该和validation Interceptor一起使用

l         servlet-config:获得对HttpServletRequestHttpServletResponse的访问(由于绑定到Servlet API,最好不要使用)

l         prepare

l         conversionError

2)创建自己的Interceptor

如果上面的Interceptor没有适合你的,你可以创建自己的Interceptor。下面的例子假设我们需要一个Interceptorsession中根据当天时间放置一个欢迎信息:

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-2.1 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>

Interceptor类要扩展com.opensymphony.xwork.interceptor.Interceptor接口:init()Interceptor初始化时调用;destroy()在销毁时调用;intercept(ActionInvocation invocation)是处理的中心。

invocation.invoke()用来调用Interceptor堆中下一个Interceptor,或是Action(如果没有的话)。因此,我们完全可以绕开Action而返回结果(不执行Action)。

上面的例子是在Action执行之前调用,如果要在Action执行之后调用Interceptor,只要将执行代码放在invocation.invoke()之后。

WebWork提供一个实现这种方式的抽象类com.opensymphony.xwork.interceptor.AroundInterceptor,你只要实现它的before(ActionInvocation invocation) after(ActionInvocation dispatcher, String result)方法就可以了。

FO: Starting Servlet Engine: Apache Tomcat/7.0.59 Sep 03, 2025 1:28:08 PM org.apache.catalina.startup.HostConfig deployDirectory INFO: Deploying web application directory /data/EnterpriseApp/TomcatApp/tomcat-7.0-bdcs_hande/webapps/bdcs Sep 03, 2025 1:28:09 PM org.apache.catalina.startup.ContextConfig processAnnotationsJar SEVERE: Unable to process Jar entry [META-INF/versions/9/module-info.class] from Jar [jar:file:/data/EnterpriseApp/TomcatApp/tomcat-7.0-bdcs_hande/webapps/bdcs/WEB-INF/lib/commons-net-3.10.0.jar!/] for annotations org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 19 at org.apache.tomcat.util.bcel.classfile.Constant.readConstant(Constant.java:97) at org.apache.tomcat.util.bcel.classfile.ConstantPool.<init>(ConstantPool.java:55) at org.apache.tomcat.util.bcel.classfile.ClassParser.readConstantPool(ClassParser.java:177) at org.apache.tomcat.util.bcel.classfile.ClassParser.parse(ClassParser.java:85) at org.apache.catalina.startup.ContextConfig.processAnnotationsStream(ContextConfig.java:2089) at org.apache.catalina.startup.ContextConfig.processAnnotationsJar(ContextConfig.java:1965) at org.apache.catalina.startup.ContextConfig.processAnnotationsUrl(ContextConfig.java:1931) at org.apache.catalina.startup.ContextConfig.processAnnotations(ContextConfig.java:1916) at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1330) at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:889) at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:386) at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5412) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:649) at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1245) at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1895) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Sep 03, 2025 1:28:10 PM org.apache.catalina.startup.TaglibUriRule body INFO: TLD skipped. URI: webwork is already defined log4j:ERROR setFile(null,true) call failed. java.io.FileNotFoundException: /logs/bdcs.log (No such file or directory) at java.io.FileOutputStream.open0(Native Method) at java.io.FileOutputStream.open(FileOutputStream.java:270) at java.io.FileOutputStream.<init>(FileOutputStream.java:213) at java.io.FileOutputStream.<init>(FileOutputStream.java:133) at org.apache.log4j.FileAppender.setFile(FileAppender.java:272) at org.apache.log4j.FileAppender.activateOptions(FileAppender.java:151) at org.apache.log4j.DailyRollingFileAppender.activateOptions(DailyRollingFileAppender.java:206) at org.apache.log4j.config.PropertySetter.activate(PropertySetter.java:247) at org.apache.log4j.config.PropertySetter.setProperties(PropertySetter.java:123) at org.apache.log4j.config.PropertySetter.setProperties(PropertySetter.java:87) at org.apache.log4j.PropertyConfigurator.parseAppender(PropertyConfigurator.java:645) at org.apache.log4j.PropertyConfigurator.parseCategory(PropertyConfigurator.java:603) at org.apache.log4j.PropertyConfigurator.configureRootCategory(PropertyConfigurator.java:500) at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:406) at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:432) at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:460) at org.apache.log4j.LogManager.<clinit>(LogManager.java:113) at org.apache.log4j.Category.getInstance(Category.java:530) at org.apache.commons.logging.impl.Log4jFactory.getInstance(Log4jFactory.java:140) at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:257) at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:390) at com.opensymphony.clickstream.ClickstreamListener.<clinit>(ClickstreamListener.java:24) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:422) at java.lang.Class.newInstance(Class.java:442) at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:116) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4932) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5524) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:649) at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1245) at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1895) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) log4j:ERROR Either File or DatePattern options are not set for appender [bdcs]. 09-03 13:28:11.438 INFO [ContextLoader.java:142] Root WebApplicationContext: initialization started 09-03 13:28:11.457 INFO [XmlBeanDefinitionReader.java:119] Loading XML bean definitions from class path resource [com/smics/apps/sso/test_sso_context.xml] 09-03 13:28:11.479 INFO [XmlBeanDefinitionReader.java:119] Loading XML bean definitions from class path resource [com/smics/apps/exporthr/test_exporthr_context.xml] 09-03 13:28:11.486 INFO [XmlBeanDefinitionReader.java:119] Loading XML bean definitions from class path resource [com/smics/apps/prodtech/prod_prodtech_context.xml] 09-03 13:28:11.500 INFO [XmlBeanDefinitionReader.java:119] Loading XML bean definitions from class path resource [com/smics/apps/bdcs/mail_content.xml] 09-03 13:28:11.501 ERROR [ContextLoader.java:172] Context initialization failed org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [com/smics/apps/bdcs/mail_content.xml]; nested exception is java.io.FileNotFoundException: class path resource [com/smics/apps/bdcs/mail_content.xml] cannot be opened because it does not exist java.io.FileNotFoundException: class path resource [com/smics/apps/bdcs/mail_content.xml] cannot be opened because it does not exist at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:127) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:131) at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:99) at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:114) at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:82) at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:87) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:262) at org.springframework.web.context.support.AbstractRefreshableWebApplicationContext.refresh(AbstractRefreshableWebApplicationContext.java:131) at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:224) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:150) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:48) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5016) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5524) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:649) at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1245) at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1895) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)什么原因
09-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值