Struts2拦截器(翻译自Struts2官方网站)

本文为本人翻译struts2的官方网站上的关于拦截器的说明文档,官方网站上的说明均是英文的,不方便热爱学习而英语又不太好的朋友。该说明文档地址是http://struts.apache.org/2.0.11/docs/interceptors.html
        许多的Struts2中的Action需要共享一些共用信息或者是模块,有些Action需要对输入进行验证,另外一些Action或许需要对文件上传之前做一些逻辑处理,又或者一些Action需要对重复提交进行保护,还有一些Actiion需要在页面显示前,初始化下拉框或一些页面组件。
        Struts2框架使用了Interceptor(拦截器)策略使共享这些关心的模块更简单的使用起来。当需要使用到一些映射到Action的资源时,框架生成了Action对象,但在该Action被执行前,执法该Action中的方法被另外一个对象拦截了,在Action执行时,可能再次被拦截,我们亲切地称此对象为拦截器。
理解拦截器
        拦截器能够在一个Action执行前后拦截它。目前的很多框架的核心实现均是基于拦截器。(本人说两句,OOP因为拦截器而显得更为精彩,AOP必将成为下一个核心关注点)。拦截器可以帮助实现很多公共的内容,其中有重复提交,类型转换,对象初始化,验证,文件上传,页面初始化等等。由于每个拦截器都可以像热插拔的模块,你可以在你的Action中正确地去使用需要的拦截器。
        拦截器可以配置在一个基类的action中,自定义的拦截器可以尽量少或者配合框架中的已有的拦截器。
所以套用句外国人的话说吧,在一个Action执行时,让我们为它再提升一些吧,给Action更大

 

的舞台更强大的力量吧。
        如上图所示,Struts2的Action被一个或者多个拦截器围绕,所有的用户请求都会被拦截器 所拦截,最后交给Action处理,处理结果以逻辑视图的方式返回给用户,调用的流程由配置文件来实现。
        在一些例子中,一个拦截器可以解决像重复提交以及验证失败这样的例子。当然也可以改变一个Action在执行前的状态。
        拦截器可以定义为一个指定执行顺序的链中,在某些情况下,拦截器的顺序非常的重要。
 ="struts-default">该元素的意思是定义了一个继承于struts-default包的包,那么该包中的所有action均可使用struts-default.xml中定义的拦截器以及拦截器链。其中注意一点,struts-default.xml中定义了一系列的拦截器和拦截器链,同时也定义了一个默认的拦截器defaultStack,一电定义了默认的拦截器,那么该拦截器将会对包中的所有的Action起作用,当然如果你的Action中显式地定义了拦截器,那么默认拦截器将会失去作用,当然如果想不让他失去作用,那么也必须显式地定义系统默认的拦截器。
        <default-interceptor-ref ..../>元素为<package../>元素的一个子元素配置,如果在某个包中定义了一个默认的拦截器,那么此拦截器将对该包中的所有的Action都是有效的,当然一定要记住,显式地定义拦截器的情况除外。
        当然除了可以使用系统提供的默认的拦截器,我们也可以自定义自己的拦截器。Struts2框架提供了一个定义拦截器的接口Interceptor接口。同时Struts2框架也提供了一个可以用于过滤拦截Action方法的类MethodFilterInterceptor。该类有两个属性excludeMethods和includeMethods。分别代表指定拦截器拒绝拦截的方法和需要拦截的方法。例:

struts.xml


<package name="default" extends="struts-default">
<interceptors>
<interceptor name="timer" class=".."/>
<interceptor name="logger" class=".."/>
</interceptors>
<action name="login"
class="tutorial.Login">
<interceptor-ref name="timer"/>
<interceptor-ref name="logger"/>
<result name="input">login.jsp</result>
<result name="success"
type="redirect-action">/secure/home</result>
</action>
</package>在大部分的Web应用中,我们发现会一再地重复应用一些拦截器的设置。重复地定义一系列的拦截器是个麻烦的事,当然我们可以绑定这些拦截器到一个链中。


struts.xml
<package name="default" extends="struts-default">
<interceptors>
<interceptor name="timer" class=".."/>
<interceptor name="logger" class=".."/>
<interceptor-stack name="myStack">
<interceptor-ref name="timer"/>
<interceptor-ref name="logger"/>
</interceptor-stack>
</interceptors>
<action name="login"
class="tutuorial.Login">
<interceptor-ref name="myStack"/>
<result name="input">login.jsp</result>
<result name="success"
type="redirect-action">/secure/home</result>
</action>
</package>
看看上面的配置如果不明白的话,再去看看struts-default.xml可以弄清楚这些拦截器都干什么了。
<?xml version="1.0" encoding="UTF-8" ?>
<!--
/*
* $Id$
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
    <bean class="com.opensymphony.xwork2.ObjectFactory" name="xwork" />
    <bean type="com.opensymphony.xwork2.ObjectFactory" name="struts" class="org.apache.struts2.impl.StrutsObjectFactory" />

    <bean type="com.opensymphony.xwork2.ActionProxyFactory" name="xwork" class="com.opensymphony.xwork2.DefaultActionProxyFactory"/>
    <bean type="com.opensymphony.xwork2.ActionProxyFactory" name="struts" class="org.apache.struts2.impl.StrutsActionProxyFactory"/>

    <bean type="com.opensymphony.xwork2.util.ObjectTypeDeterminer" name="tiger" class="com.opensymphony.xwork2.util.GenericsObjectTypeDeterminer"/>
    <bean type="com.opensymphony.xwork2.util.ObjectTypeDeterminer" name="notiger" class="com.opensymphony.xwork2.util.DefaultObjectTypeDeterminer"/>
    <bean type="com.opensymphony.xwork2.util.ObjectTypeDeterminer" name="struts" class="com.opensymphony.xwork2.util.DefaultObjectTypeDeterminer"/>

    <bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="struts" class="org.apache.struts2.dispatcher.mapper.DefaultActionMapper" />
    <bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="composite" class="org.apache.struts2.dispatcher.mapper.CompositeActionMapper" />
    <bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="restful" class="org.apache.struts2.dispatcher.mapper.RestfulActionMapper" />
    <bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="restful2" class="org.apache.struts2.dispatcher.mapper.Restful2ActionMapper" />

    <bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="struts" class="org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest" scope="default" optional="true"/>
    <bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="jakarta" class="org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest" scope="default" optional="true" />

    <bean type="org.apache.struts2.views.TagLibrary" name="s" class="org.apache.struts2.views.DefaultTagLibrary" />

    <bean class="org.apache.struts2.views.freemarker.FreemarkerManager" name="struts" optional="true"/>
    <bean class="org.apache.struts2.views.velocity.VelocityManager" name="struts" optional="true" />

    <bean class="org.apache.struts2.components.template.TemplateEngineManager" />
    <bean type="org.apache.struts2.components.template.TemplateEngine" name="ftl" class="org.apache.struts2.components.template.FreemarkerTemplateEngine" />
    <bean type="org.apache.struts2.components.template.TemplateEngine" name="vm" class="org.apache.struts2.components.template.VelocityTemplateEngine" />
    <bean type="org.apache.struts2.components.template.TemplateEngine" name="jsp" class="org.apache.struts2.components.template.JspTemplateEngine" />

    <bean type="com.opensymphony.xwork2.util.XWorkConverter" name="xwork1" class="com.opensymphony.xwork2.util.XWorkConverter" />
    <bean type="com.opensymphony.xwork2.util.XWorkConverter" name="struts" class="com.opensymphony.xwork2.util.AnnotationXWorkConverter" />

    <bean type="com.opensymphony.xwork2.TextProvider" name="xwork1" class="com.opensymphony.xwork2.TextProviderSupport" />
    <bean type="com.opensymphony.xwork2.TextProvider" name="struts" class="com.opensymphony.xwork2.TextProviderSupport" />

<bean type="org.apache.struts2.components.UrlRenderer" name="struts" class="org.apache.struts2.components.ServletUrlRenderer"/>

    <!--  Only have static injections -->
    <bean class="com.opensymphony.xwork2.ObjectFactory" static="true" />
    <bean class="com.opensymphony.xwork2.util.XWorkConverter" static="true" />
    <bean class="com.opensymphony.xwork2.util.OgnlValueStack" static="true" />
    <bean class="org.apache.struts2.dispatcher.Dispatcher" static="true" />
    <bean class="org.apache.struts2.components.Include" static="true" />
    <bean class="org.apache.struts2.dispatcher.FilterDispatcher" static="true" />
    <bean class="org.apache.struts2.views.util.ContextUtil" static="true" />
    <bean class="org.apache.struts2.views.util.UrlHelper" static="true" />

    <package name="struts-default" abstract="true">
        <result-types>
            <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
            <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
            <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
            <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
            <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
            <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
            <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
            <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
            <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
            <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
        </result-types>

        <interceptors>
            <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
            <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
            <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
            <interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>
            <interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" />
            <interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />
            <interceptor name="externalRef" class="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor"/>
            <interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>
            <interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>
            <interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
            <interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>
            <interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
            <interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
            <interceptor name="scopedModelDriven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
            <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
            <interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
            <interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
            <interceptor name="scope" class="org.apache.struts2.interceptor.ScopeInterceptor"/>
            <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
            <interceptor name="sessionAutowiring" class="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor"/>
            <interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
            <interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>
            <interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
            <interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>
            <interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
            <interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" />
            <interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" />
            <interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />
            <interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" />
            <interceptor name="jsonValidation" class="org.apache.struts2.interceptor.validation.JSONValidationInterceptor" />
            <interceptor name="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor" />

            <!-- Basic stack -->
            <interceptor-stack name="basicStack">
                <interceptor-ref name="exception"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="prepare"/>
                <interceptor-ref name="checkbox"/>
                <interceptor-ref name="params"/>
                <interceptor-ref name="conversionError"/>
            </interceptor-stack>

            <!-- Sample validation and workflow stack -->
            <interceptor-stack name="validationWorkflowStack">
                <interceptor-ref name="basicStack"/>
                <interceptor-ref name="validation"/>
                <interceptor-ref name="workflow"/>
            </interceptor-stack>
           
            <!-- Sample JSON validation stack -->
            <interceptor-stack name="jsonValidationWorkflowStack">
                <interceptor-ref name="basicStack"/>
                <interceptor-ref name="validation">
                    <param name="excludeMethods">input,back,cancel</param>
                </interceptor-ref>
                <interceptor-ref name="jsonValidation"/>
                <interceptor-ref name="workflow"/>
            </interceptor-stack>

            <!-- Sample file upload stack -->
            <interceptor-stack name="fileUploadStack">
                <interceptor-ref name="fileUpload"/>
                <interceptor-ref name="basicStack"/>
            </interceptor-stack>

            <!-- Sample model-driven stack  -->
            <interceptor-stack name="modelDrivenStack">
                <interceptor-ref name="modelDriven"/>
                <interceptor-ref name="basicStack"/>
            </interceptor-stack>

            <!-- Sample action chaining stack -->
            <interceptor-stack name="chainStack">
                <interceptor-ref name="chain"/>
                <interceptor-ref name="basicStack"/>
            </interceptor-stack>

            <!-- Sample i18n stack -->
            <interceptor-stack name="i18nStack">
                <interceptor-ref name="i18n"/>
                <interceptor-ref name="basicStack"/>
            </interceptor-stack>

            <!-- An example of the params-prepare-params trick. This stack
                 is exactly the same as the defaultStack, except that it
                 includes one extra interceptor before the prepare interceptor:
                 the params interceptor.

                 This is useful for when you wish to apply parameters directly
                 to an object that you wish to load externally (such as a DAO
                 or database or service layer), but can't load that object
                 until at least the ID parameter has been loaded. By loading
                 the parameters twice, you can retrieve the object in the
                 prepare() method, allowing the second params interceptor to
                 apply the values on the object. -->
            <interceptor-stack name="paramsPrepareParamsStack">
                <interceptor-ref name="exception"/>
                <interceptor-ref name="alias"/>
                <interceptor-ref name="params"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="prepare"/>
                <interceptor-ref name="i18n"/>
                <interceptor-ref name="chain"/>
                <interceptor-ref name="modelDriven"/>
                <interceptor-ref name="fileUpload"/>
                <interceptor-ref name="checkbox"/>
                <interceptor-ref name="staticParams"/>
                <interceptor-ref name="params"/>
                <interceptor-ref name="conversionError"/>
                <interceptor-ref name="validation">
                    <param name="excludeMethods">input,back,cancel</param>
                </interceptor-ref>
                <interceptor-ref name="workflow">
                    <param name="excludeMethods">input,back,cancel</param>
                </interceptor-ref>
            </interceptor-stack>

            <!-- A complete stack with all the common interceptors in place.
                 Generally, this stack should be the one you use, though it
                 may do more than you need. Also, the ordering can be
                 switched around (ex: if you wish to have your servlet-related
                 objects applied before prepare() is called, you'd need to move
                 servlet-config interceptor up.

                 This stack also excludes from the normal validation and workflow
                 the method names input, back, and cancel. These typically are
                 associated with requests that should not be validated.
                 -->
            <interceptor-stack name="defaultStack">
                <interceptor-ref name="exception"/>
                <interceptor-ref name="alias"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="prepare"/>
                <interceptor-ref name="i18n"/>
                <interceptor-ref name="chain"/>
                <interceptor-ref name="debugging"/>
                <interceptor-ref name="profiling"/>
                <interceptor-ref name="scopedModelDriven"/>
                <interceptor-ref name="modelDriven"/>
                <interceptor-ref name="fileUpload"/>
                <interceptor-ref name="checkbox"/>
                <interceptor-ref name="staticParams"/>
                <interceptor-ref name="params">
                  <param name="excludeParams">dojo\..*</param>
                </interceptor-ref>
                <interceptor-ref name="conversionError"/>
                <interceptor-ref name="validation">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
                <interceptor-ref name="workflow">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
            </interceptor-stack>

            <!-- The completeStack is here for backwards compatibility for
                 applications that still refer to the defaultStack by the
                 old name -->
            <interceptor-stack name="completeStack">
                <interceptor-ref name="defaultStack"/>
            </interceptor-stack>

            <!-- Sample execute and wait stack.
                 Note: execAndWait should always be the *last* interceptor. -->
            <interceptor-stack name="executeAndWaitStack">
                <interceptor-ref name="execAndWait">
                    <param name="excludeMethods">input,back,cancel</param>
                </interceptor-ref>
                <interceptor-ref name="defaultStack"/>
                <interceptor-ref name="execAndWait">
                    <param name="excludeMethods">input,back,cancel</param>
                </interceptor-ref>
            </interceptor-stack>

       </interceptors>

        <default-interceptor-ref name="defaultStack"/>
    </package>

</struts>
看看上面的struts-default.xml中的默认配置,都已经事先定义了若干个拦截器使用。
        拦截器的类已经定义在特殊的配置文件中,这个配置文件的名字就叫做struts-default.xml,如果你继承了struts-default默认的包名,那你就可以使用这些拦截器了,否则你必须在你自己的包中定义拦截器在<interceptors>中进行定义。

Interceptor  Name  Description 
Alias Interceptor  alias  在不同的请求之间将参数在不同的名字间转换,请求内容不变. 
Chaining Interceptor  chain  让前面一个Action的属性可以被后一个Action访问
Checkbox Interceptor  checkbox  Adds automatic checkbox handling code that detect an unchecked checkbox and add it as a parameter with a default (usually 'false') value. Uses a specially named hidden field to detect unsubmitted checkboxes. The default unchecked value is overridable for non-boolean value'd checkboxes. 
Cookie Interceptor  cookie  使用配置的name、value来设置cookies
Conversion Error Interceptor  conversionError  将错误从ActionContext中添加到Action的属性字段中
Create Session Interceptor  createSession  自动地创建HttpSession,用来为需要使用到HttpSession的拦截器服务
DebuggingInterceptor  debugging  提供不同的调试用的页面来展示内部的数据状况
Execute and Wait Interceptor  execAndWait  在后台执行Action,同时将用户带到一个中间的等待页面
Exception Interceptor  exception  将异常定位到一个页面
File Upload Interceptor  fileUpload  提供文件上传功能
I18n Interceptor  i18n  记录用户选择的locale
Logger Interceptor  logger  输出Action的名字
Message Store Interceptor  store  存储或者访问实现ValidationAware接口的Action类出现的消息、错误、字段错误等。
Model Driven Interceptor  model-driven  如果一个类实现了ModelDriven,将getModel得到的结果放在ValueStack中
Scoped Model Driven Interceptor  scoped-model-driven  如果一个Action实现了ScopedModelDriven,则这个拦截器会从相应的Scope中取出model,调用Action的setModel方法将其放入Action内部
Parameters Interceptor  params  将请求中的参数设置到Action中去
Prepare Interceptor  prepare  如果Action实现了Preparable,则该拦截器调用Action类的prepare方法
Scope Interceptor  scope  将Action状态存入Session和Application的简单方法
Servlet Config Interceptor  servletConfig  提供访问HttpServletRequest和HttpServletResponse的方法,以Map的方式访问
Static Parameters Interceptor  staticParams  从struts.xml文件中将<action>中的<param>下的内容设置到对应的Action中
Roles Interceptor  roles  确定用户是否具有JAAS指定的Role,否则不予执行
Timer Interceptor  timer  输出Action执行的时间
Token Interceptor  token  通过Token来避免双击
Token Session Interceptor  tokenSession  和Token Interceptory一样,不过双击的时候把请求的数据存储在Session中
Validation Interceptor  validation  使用action-validation.xml文件中定义的内容校验提交的数据
Workflow Interceptor  workflow  调用Action的validate的方法,一旦有错返回,重新定位到INPUT页面
Parameter Filter Interceptor  N/A  从参数列表中删除不必要的参数
Profiling Interceptor  profiling  通过参数激活profile


个人理解
        在struts.xml配置文件中,如果要定义拦截器,需要为拦截器类指定一个拦截器名。定义以<interceptor../>元素来实现。还可以定义<param../>参数子元素,用来对拦截器的参数初始化。当然除了可以定义拦截器还可以定义拦截器栈,我也把它称之为拦截器链。拦截器栈由多个拦截器 组成的一个拦截器链。定义拦截器链使用<interceptor-stack../>元素,当然在这个元素中还需要定义大量的<interceptor-ref ../>,即该拦截器链所包含的拦截器引用。在拦截器链定义的<interceptor-ref.../>元素中,其name除了可以是一个拦截器的名称,也可以是一个其它的拦截器链。拦截器链与拦截器在本质上并无区别,目的都是为了进行拦截。大家可以去看看struts-default.xml配置文件,其中定义了很多拦截器以及拦截器链。其中有一个定义为<default-interceptor-ref name="defaultStack"/>意思是定义了一个默认的拦截器链,只要是继承了struts-default包的包均有该默认的拦截器,当然你也可以定义自己的默认的拦截器链。<package name="***" extends

public class FilterInterceptor extends MethodFilterInterceptor{
 private String name;
 protected String doIntercept(ActionInvocation arg0)throws Exception{
  //HelloWorld hw=(HelloWorld)arg0.getAction();
  String res=arg0.invoke();
  return res;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }

}

再看看struts.xml配置文件
    <package name="struts2tutoial" extends="struts-default">
        <interceptors>
            <interceptor name="MyInterceptor" class="interceptor.MyInterceptor"/>
            <interceptor name="FilterInterceptor" class="interceptor.FilterInterceptor"/>
        </interceptors>
        <action name="HelloWorld" class="helloWorld">
            <result>/helloWorld.jsp</result>
            <interceptor-ref name="defaultStack"/>
            <interceptor-ref name="MyInterceptor"/>
            <interceptor-ref name="FilterInterceptor">
                <param name="includeMethods">***</param>
                <param name="excludeMethods">***</param>
            </interceptor-ref>
        </action>
    </package>
可以看到<param../>元素在此处发挥了作用,自定义的FilterInterceptor起到了过滤方法的作用。
欢迎网友参与讨论交流!

本博客来自于:http://www.blogjava.net/zhoumiao0123/archive/2008/08/10/221088.html

你可能感兴趣的:(apache,应用服务器,bean,struts,workflow)