zoukankan      html  css  js  c++  java
  • 第5章 Struts 2的拦截器

    5.1 拦截器概述

    Struts 2框架内建了大量的拦截器,这些拦截器可以在Struts 2的配置文件struts-default.xml中查看

    Struts 2框架给出了这么多的拦截器,下面简要介绍它们的作用。

    <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="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" />

    l alias:实现在不同请求中相似参数别名的转换。

    l autowiring:这是个自动装配Spring,主要用于当Struts 2和Spring整合时,Struts 2可以使用自动装配的方式来访问Spring容器中的Bean。

    l chain:构建一个Action链,使当前Action可以访问前一个Action的属性,一般和<result type="chain"/>一起使用。

    l conversionError:这是一个负责处理类型转换错误的拦截器,它负责将类型转换错误从ActionContext中取出,并转换成Action的FieldError错误。

    l createSession:该拦截器负责创建一个HttpSession对象,主要用于那些需要有HttpSession对象才能正常工作的拦截器。

    l debugging:当使用Struts 2的开发模式时,这个拦截器会提供更多的调试信息。

    l execAndWait:后台执行Action,负责将等待画面发送给用户。

    l exception:这个拦截器负责处理异常,它将异常映射为结果。

    l fileUpload:这个拦截器主要用于文件上传,它负责解析表单中文件域的内容。

    l il8n:这是支持国际化的拦截器,它负责把所选的语言、区域放入用户Session中。

    l logger:这是一个负责日志记录的拦截器,主要是输出Action的名字。

    l model-driven:这是一个用于模型驱动的拦截器,当某个Action类实现了ModeiDriven接口时,它负责把getModel()方法的结果堆入ValueStack中。

    l scoped-model-driven:如果一个Action实现了一个ScopedModeiDriven接口,该拦截器负责从指定生存范围中找出指定的Model,并将通过setModel方法将该Model传给Action实例。

    l params:这是一个最基本的拦截器,它负责解析HTTP请求中的参数,并将参数值设置成Action对应的属性值。

    l prepare:如果action实现了Preparable接口,将会调用该拦截器的prepare()方法。

    l static-params:这个拦截器负责将xml中<action>标签下<param>标签中的参数传入action。

    l scope:这是范围转换拦截器,它可以将Action状态信息保存到HttpSession范围,或者保存到ServletContext范围内。

    l servlet-config:如果某个Action需要直接访问Servlet API,可以通过这个拦截器实现。

    l roles:这是一个JAAS(Java Authentication and Authorization Service,Java授权和认证服务)拦截器,只有当浏览者取得合适的授权后,才可以调用被该拦截器拦截的Action。

    l timer:这个拦截器负责输出Action的执行时间,在分析该Action的性能瓶颈时比较有用。

    l token:这个拦截器主要用于阻止重复提交,它检查传到Action中的token,防止多次提交。

    l token-session:这个拦截器的作用与前一个基本类似,只是它把token保存在HttpSession中。

    l validation:通过执行在xxxAction-validation.xml中定义的校验器,完成数据校验。

    l workflow:这个拦截器负责调用Action类中的validate方法,如果校验失败,则返回input的逻辑视图。

    5.2 拦截器的配置

    拦截器的配置是在struts.xml中完成的,定义一个拦截器使用<interceptor…/>标签,其格式如下:

    <interceptor name="拦截器名" class="拦截器实现类"></interceptor>

    这种情况的应用非常广。有的时候,如果需要在配置拦截器时就为其传入拦截器参数,只要在<interceptor..>与</interceptor>之间配置<param…/>标签即可传入相应的参数。其格式如下:

    <interceptor name="拦截器名" class="拦截器实现类 ">

    <param name="参数名">参数值</param>

    ...//如果需要传入多个参数,可以一并设置

    </interceptor>

    如果在其他的拦截器配置中出现了同名的参数,则前面配置的参数将被覆盖掉。

    在struts.xml中可以配置多个拦截器,它们被包在<interceptors></interceptors>之间,例如下面的配置:

    <?xml version="1.0" encoding="UTF-8" ?>

    <!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">

    <struts>

    <package name="default" extends="struts-default">

    <interceptors>

    <interceptor name="拦截器名1" class="拦截器类1"></interceptor>

    <interceptor name="拦截器名2" class="拦截器类2"></interceptor>

    ...

    <interceptor name="拦截器名n" class="拦截器类n"></interceptor>

    </interceptors>

    ...//action配置

    </package>

    </struts>

    可以看出,拦截器是配置在包下的。在包下配置了一系列的拦截器,但仅仅是配置在该包下,并没有得到应用。如果要应用这些拦截器,就需要在<action>配置中引用这些拦截器,一个<action>需要应用多个拦截器,就不免要有多条引用语句(引用拦截器用标签<interceptor-ref.../>),所以Struts 2给出了拦截器栈的使用,一个拦截器栈中可以包含多个拦截器,配置拦截器栈的格式为

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">
    <struts>
          <package name="default" extends="struts-default">
            <interceptors>
                <interceptor name="拦截器名1" class="拦截器类1"></interceptor>
                <interceptor name="拦截器名2" class="拦截器类2"></interceptor>
                <interceptor name="拦截器名n" class="拦截器类n"></interceptor>
                <interceptor-stack name="拦截器栈名">
                    <interceptor-ref name="拦截器名1"></interceptor-ref>
                    <interceptor-ref name="拦截器名2"></interceptor-ref>
                    ...//这里还可以配置很多拦截器,但是前提是这些拦截器已经配置存在
                </interceptor-stack>
            </interceptors>   
        </package>
    </struts>

    其实,在Struts 2框架中也配置有很多拦截器栈,在Struts 2的struts-default.xml中可以发现有如下拦截器栈的配置

    <!-- 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 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>
    <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>
    <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>
    <interceptor-stack name="completeStack">
        <interceptor-ref name="defaultStack" />
    </interceptor-stack>
    <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>

    在struts-default.xml文件的最后还有这样一句代码:

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

    拦截器或拦截器栈配置完成后就可以在<action>中对其引用了,一个action引用拦截器或拦截器栈的格式如下:

    <action name="Action名" class="Action类">

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

    <interceptor-ref name="拦截器1"></interceptor-ref>

    <interceptor-ref name="拦截器2"></interceptor-ref>

    </action>

    可以看出,在为action指定拦截器时,配置了

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

    5.3 自定义拦截器类

    Struts 2提供了一些接口或类供程序员自定义拦截器。例如,Struts 2提供了com.opensymphony.xwork2.interceptor.Interceptor接口,程序员只要实现该接口就可完成自定义拦截器类的编写。该接口的代码如下:

     public interface Interceptor extends Serializable{

    void init();

    String intercept(ActionInvocation invocation) throws Exception;

    void destroy();

    }

    该接口中有如下三种方法。

    l init():该方法在拦截器被实例化之后、拦截器执行之前调用。该方法只被执行一次,主要用于初始化资源。

    l intercept(ActionInvocation invocation):该方法用于实现拦截的动作。该方法有个参数,用该参数调用invoke()方法,将控制权交给下一个拦截器,或者交给Action类的方法。

    l destroy():该方法与init()方法对应,拦截器实例被销毁之前调用。用于销毁在init()方法中打开的资源

    除了Interceptor接口之外,Struts 2框架还提供了AbstractInterceptor类,该类实现了Interceptor接口,并提供了init()方法和destroy()方法的空实现。在一般的拦截器实现中,都会继承该类,因为一般实现的拦截器是不需要打开资源的,故无须实现这两种方法,继承该类会更简洁。该类的代码实现为:

    public interface AbstractInterceptor implements Interceptor{

    public AbstractInterceptor();

    public void init();

    public void destroy();

    public abstract String intercept(ActionInvocation invocation) throws Exception;

    }

         5.3.1  实例说明自定义拦截器的应用

    首先创建项目(InterceptorTest)、加载Struts 2类库及修改web.xml,创建自定义拦截器类“MyInterceptor.java”,编写代码如下:

    package org.interceptor;

    import com.opensymphony.xwork2.ActionInvocation;

    import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

    public class MyInterceptor extends AbstractInterceptor{

    public String intercept(ActionInvocation arg0) throws Exception {

    System.out.println("我在Action前执行---->");

    String result=arg0.invoke();

    System.out.println("我在Action后执行---->");

    return result;

    }

    }

    创建Action类“TestAction.java”,编写代码如下:

    package org.action;

    import com.opensymphony.xwork2.ActionSupport;

    public class TestAction extends ActionSupport{

    public String execute() throws Exception {

    System.out.println("我在Action中执行---->");

    return NONE; //不做任何跳转

    }

    }

    在struts.xml中配置action配置及拦截器配置,代码如下:

    <?xml version="1.0" encoding="UTF-8" ?>

    <!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">

    <struts>

    <package name="default" extends="struts-default">

    <interceptors>

    <interceptor name="myInterceptor" class="org.interceptor.MyInterceptor"/>

    </interceptors>

    <action name="test" class="org.action.TestAction">

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

    <interceptor-ref name="myInterceptor"></interceptor-ref>

    </action>

    </package>

    </struts>

            做这些简单的工作后,部署项目并启动服务器,在浏览器中输入“http://localhost:8080/InterceptorTest/test.action”请求,再查看控制台,

             出现如图5.1所示的界面,可见,自定义拦截器起了作用,在Action执行前后分别输出了一句话

              image

              5.3.2 应用拦截器处理重复提交

    创建项目(本书将该项目命名为TokenInterceptor),加载Struts 2类库,修改web.xml文件,修改index.jsp作为登录页面:

    <%@ page language="java" pageEncoding="UTF-8"%>

    <%@ taglib uri="/struts-tags" prefix="s"%>

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    <html>

    <head>

    <title>登录界面</title>

    </head>

    <body>

    <s:form action="login" method="post">

    <!-- 该标签在标签库中已做解释 -->

    <s:token></s:token>

    <s:textfield name="username" label="用户名"></s:textfield>

    <s:password name="password" label="密码"></s:password>

    <s:submit value="提交"></s:submit>

    </s:form>

    </body>

    </html>

    Action类LoginAction.java为:

    package org.action;

    import com.opensymphony.xwork2.ActionSupport;

    public class LoginAction extends ActionSupport{

    private String username;

    private String password;

    //省略上述属性的get和set方法

    public String execute() throws Exception {

    return SUCCESS;

    }

    }

    在struts.xml中配置action及拦截器如下:

    <?xml version="1.0" encoding="UTF-8" ?>

    <!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">

    <struts>

    <package name="default" extends="struts-default">

    <action name="login" class="org.action.LoginAction">

    <result>/welcome.jsp</result>

    <result name="invalid.token">/wrong.jsp</result>

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

    <interceptor-ref name="token"></interceptor-ref>

    </action>

    </package>

    </struts>

    成功返回界面welcome.jsp:

    <%@ page language="java" pageEncoding="UTF-8"%>

    <%@ taglib uri="/struts-tags" prefix="s"%>

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    <html>

    <head>

    <title>欢迎界面</title>

    </head>

    <body>

    欢迎您!<s:property value="username"/>

    </body>

    </html>

    重复提交的提示错误界面wrong.jsp:

    <%@ page language="java" pageEncoding="UTF-8"%>

    <%@ taglib uri="/struts-tags" prefix="s"%>

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    <html>

    <head>

    <title>错误界面</title>

    </head>

    <body>

    对不起,请不要重复提交,单击<a href="index.jsp">这里</a>返回登录页面

    </body>

    </html>

               部署运行该项目,登录界面如图5.2所示;输入用户名和密码进入成功界面,如图5.3所示

            image

    5.3 自定义拦截器类

  • 相关阅读:
    最近这段时间我,想在2008 的基础上,写2011 有的工具 不知道会样,这次又机会研究ploy
    Screen 可以查找屏幕pos系类的函数
    笔记1
    Ubuntu下如何安装 tar.bz2 文件
    安装ubuntu遇到“BusyBox”问题
    android luancher 如何添加快捷方式
    转 Android 源代码结构
    修改apk图标
    Linux Ubuntu 下如何安装 .SH文件
    解放你的电源键!!不用刷机不用装软件!超简单修改搜索锁屏、HOME键唤醒~~~~~
  • 原文地址:https://www.cnblogs.com/elite-2012/p/4344717.html
Copyright © 2011-2022 走看看