首页 > 代码库 > Struts2拦截器详解

Struts2拦截器详解

作者:禅楼望月

1. Struts2内置拦截器

Struts2内置了大量的拦截器,如下图:

图片来自:刘水镜的博客:菜鸟学SSH(四)——Struts2拦截器

image

这些拦截器以name-class的形式配置在struts-default.xml中:

<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="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/>            <interceptor name="cookieProvider" class="org.apache.struts2.interceptor.CookieProviderInterceptor"/>            <interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor" />            <interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" />            <interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />            <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="actionMappingParams" class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/>            <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="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="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor" />            <interceptor name="multiselect" class="org.apache.struts2.interceptor.MultiselectInterceptor" />            <interceptor name="deprecation" class="org.apache.struts2.interceptor.DeprecationInterceptor" />

其中name为拦截器的名字(拦截器的唯一标识),class指定该拦截器的实现类。如果我们的package继承自struts-default包,则可以自由使用上面的拦截器,否者必须自己定义这些拦截器。

2.配置拦截器

<interceptor name="拦截器的名字" class="拦截器的实现类">    <param name="参数名">参数值</param></interceptor>

其中<param 是可选的。

当需要依次进行多个操作时还可以将这几个拦截器连在一起组成连接器栈:

<interceptors>        <interceptor name="拦截器的名字" class="拦截器的实现类">            <param name="参数名">参数值</param>        </interceptor>        <interceptor name="拦截器1" class="interceptor1"/>        <interceptor name="拦截器2" class="interceptor2"/>        <interceptor name="拦截器3" class="interceptor3"/>                <interceptor-stack name="拦截器栈名">            <interceptor-ref name="拦截器1"/>            <interceptor-ref name="拦截器2"/>            <interceptor-ref name="拦截器3"/>        </interceptor-stack>    </interceptors>

image

由上面的代码可以看出拦截器栈是由<interceptor-stack 定义的,然后使用<interceptor-ref 来引用已成在的拦截器,组成一个拦截器栈。它其实就是一个大的拦截器。和拦截器一样,它们都会在Action的execute方法之前自动执行。

拦截器栈就是一个大的拦截器。这说明拦截器中可以包含拦截器栈:

<interceptors>    <interceptor name="拦截器的名字" class="拦截器的实现类">        <param name="参数名">参数值</param>    </interceptor>    <interceptor name="拦截器1" class="interceptor1"/>    <interceptor name="拦截器2" class="interceptor2"/>    <interceptor name="拦截器3" class="interceptor3"/>    <interceptor name="拦截器4" class="interceptor4"/>        <interceptor-stack name="拦截器栈1">        <interceptor-ref name="拦截器1"/>        <interceptor-ref name="拦截器2"/>        <interceptor-ref name="拦截器3"/>    </interceptor-stack>        <interceptor-stack name="拦截器栈2">        <interceptor-ref name="拦截器4"/>        <interceptor-ref name="拦截器栈1"/>    </interceptor-stack></interceptors>
系统为拦截器指定参数有如下两个时机:

  1. 定义拦截器时(即通过<interceptor 元素来定义拦截器)指定参数值:这种参数值将作为拦截器参数的默认参数值。
  2. 使用拦截器时(即通过<interceptor-ref 元素来使用拦截器)指定参数:在配置Action时为拦截器参数指定值,用于覆盖拦截器的默认参数值。

通过为<interceptor-ref 元素增加<param 子元素,就可以在使用拦截器时为参数指定值。

3.使用拦截器

拦截器(包括拦截器栈)的拦截行为会在Action的execute方法之前自动执行。通过<interceptor-ref 可以在Action中使用拦截器,在Action中使用拦截器的配置语法与配置拦截器栈时引用拦截器的语法完全一样。

<package name="syxpj"  extends="struts-default" namespace="/syxpj">    <interceptors>        <interceptor name="拦截器的名字" class="拦截器的实现类">            <param name="参数名">参数值</param>        </interceptor>        <interceptor name="拦截器1" class="interceptor1"/>        <interceptor name="拦截器2" class="interceptor2"/>        <interceptor name="拦截器3" class="interceptor3"/>        <interceptor name="拦截器4" class="interceptor4">            <param name="arg1">arg1</param>        </interceptor>                <interceptor-stack name="拦截器栈1">            <interceptor-ref name="拦截器1"/>            <interceptor-ref name="拦截器2"/>            <interceptor-ref name="拦截器3"/>        </interceptor-stack>                <interceptor-stack name="拦截器栈2">            <interceptor-ref name="拦截器4"/>            <interceptor-ref name="拦截器栈1"/>        </interceptor-stack>    </interceptors>        <action name="action1" class="class1">        <result name="success">welcome.jsp</result>        <result name="error">err.jsp</result>        <!-- 使用系统默认的拦截器栈 -->        <interceptor-ref name="defaultStack"/>        <interceptor-ref name="拦截器栈2"/> 
        <interceptor-ref name="拦截器4">
            <param name="arg1">覆盖了默认参数</param>        </interceptor-ref>    </action></package>

4.配置默认拦截器

使用为<default-interceptor-ref 子元素一个配置默认拦截器。为一个包配置默认拦截器后,当一个action没有显式配置一个拦截器时该默认拦截器才会生效,否则默认拦截器不起作用。并且每个包至多只能有一个默认拦截器。

配置默认拦截器也是一种使用拦截器的方式,因此,在配置默认拦截器是指定参数也会覆盖拦截器指定的默认参数值。

在struts-default.xml中有这样一段代码:

image

有上图可知Struts2在struts-default包中定义了一个默认的拦截器栈引用:defaultStack。因此当我们定义的包继承自struts-default包时也继承了它的默认拦截器引用:defaultStack,当我们不为Action显式的应用拦截器,则defaultStack栈会起作用。

欢迎转载,请注明出处。

Struts2拦截器详解