zoukankan      html  css  js  c++  java
  • Struts2拦截器

    对于Struts中的标签这里就不一一列举了,标签也比较简单,所以就跳过,会用就好了,今天主要说下拦截器。拦截器interceptor类似于Filter,在执行Action方法前后执行,拦截器是一种AOP面向切片编程思想的编程方式。提供了一种机制使开发者能把相对独立的代码抽象出来,配置到Action前后执行。Filter中有Filter链在拦截器中有拦截栈,在Action前后被一次执行。Struts2内置了许多现成的拦截器,Struts2的某些功能如数据转换、数据校验等也是基于拦截器实现的。这些拦截器配置在struts-default.xml中,如果需要这些功能直接使用即可。下面举几个常用的拦截器的列子。

    <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="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="org.apache.struts2.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="datetime" class="org.apache.struts2.interceptor.DateTextFieldInterceptor" />
                <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" />
    
                <!-- 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="datetime"/>
                    <interceptor-ref name="multiselect"/>
                    <interceptor-ref name="actionMappingParams"/>
                    <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>
    
                <!-- An example of the paramsPrepareParams 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="i18n"/>
                    <interceptor-ref name="checkbox"/>
                    <interceptor-ref name="datetime"/>
                    <interceptor-ref name="multiselect"/>
                    <interceptor-ref name="params"/>
                    <interceptor-ref name="servletConfig"/>
                    <interceptor-ref name="prepare"/>
                    <interceptor-ref name="chain"/>
                    <interceptor-ref name="modelDriven"/>
                    <interceptor-ref name="fileUpload"/>
                    <interceptor-ref name="staticParams"/>
                    <interceptor-ref name="actionMappingParams"/>
                    <interceptor-ref name="params"/>
                    <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>
    
                <!-- 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
                     servletConfig 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="i18n"/>
                    <interceptor-ref name="prepare"/>
                    <interceptor-ref name="chain"/>
                    <interceptor-ref name="scopedModelDriven"/>
                    <interceptor-ref name="modelDriven"/>
                    <interceptor-ref name="fileUpload"/>
                    <interceptor-ref name="checkbox"/>
                    <interceptor-ref name="datetime"/>
                    <interceptor-ref name="multiselect"/>
                    <interceptor-ref name="staticParams"/>
                    <interceptor-ref name="actionMappingParams"/>
                    <interceptor-ref name="params"/>
                    <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-ref name="debugging"/>
                </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"/>
    View Code

    拦截器

    名字

    说明

    Alias Interceptor

    alias

    在不同请求之间将请求参数在不同名字件转换,请求内容不变

    Chaining Interceptor

    chain

    让前一个Action的属性可以被后一个Action访问,现在和chain类型的result<result type=”chain”>)结合使用。

    Checkbox Interceptor

    checkbox

    添加了checkbox自动处理代码,将没有选中的checkbox的内容设定为false,而html默认情况下不提交没有选中的checkbox

    Cookies Interceptor

    cookies

    使用配置的name,value来是指cookies

    Conversion Error Interceptor

    conversionError

    将错误从ActionContext中添加到Action的属性字段中。

    Create Session Interceptor

    createSession

    自动的创建HttpSession,用来为需要使用到HttpSession的拦截器服务。

    Debugging Interceptor

    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得到的结果放在Value Stack中。

    Scoped Model Driven

    scoped-model-driven

    如果一个Action实现了ScopedModelDriven,则这个拦截器会从相应的Scope中取出model调用ActionsetModel方法将其放入Action内部。

    Parameters Interceptor

    params

    将请求中的参数设置到Action中去。

    Prepare Interceptor

    prepare

    如果Acton实现了Preparable,则该拦截器调用Action类的prepare方法。

    Scope Interceptor

    scope

    Action状态存入sessionapplication的简单方法。

    Servlet Config Interceptor

    servletConfig

    提供访问HttpServletRequestHttpServletResponse的方法,以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 Interceptor一样,不过双击的时候把请求的数据存储在Session

    Validation Interceptor

    validation

    使用action-validation.xml文件中定义的内容校验提交的数据。

    Workflow Interceptor

    workflow

    调用Actionvalidate方法,一旦有错误返回,重新定位到INPUT画面

    Parameter Filter Interceptor

    N/A

    从参数列表中删除不必要的参数

    Profiling Interceptor

    profiling

    通过参数激活profile

    一、Token防重复提交拦截器

    token拦截器用于保证表单只被提交一次,如果再次提交该表单,拦截器会拦截请求,防止提交重复数据。它的原理是显示表单的时候在session中对该表单做一个标记,该标记只能使用一次,使用过后就失效,从而保证表单最多只提交一次数据。重复提交数据会因为标记已失效而提交失败。首先定义Action。这里定义了一个TokenAction。

    package com.cyw.test;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    public class TokenAction extends ActionSupport {
    
        private String name;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public String execute() throws Exception {
        
            return "success";
        }
    }
    View Code

    2.表单设置

    这里主要是在表单中增加 <struts:token></struts:token>标签。

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
        <%@ taglib uri="/struts-tags" prefix="struts" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>注册页面</title>
    </head>
    <body>
    <struts:fielderror></struts:fielderror>
        <struts:form action="token" method="post">  
        <struts:token></struts:token>
        <struts:textfield name="name" label="用户名"></struts:textfield>
        <br/>  
        <struts:submit value="注册"></struts:submit>   
        </struts:form>   
    </body>
    </html>
    View Code

    3.拦截器配置

    在struts.xml中增加配置,配置token拦截器。Action中必须配置一个invalid.token的result页面。如果重复提交会跳转到该页面中。

            <action name="token"  class="com.cyw.test.TokenAction">
                <interceptor-ref name="token"></interceptor-ref>
                <interceptor-ref name="basicStack"></interceptor-ref>
                <result name="success">/success.jsp</result>
                <result name="input">/register.jsp</result>    
                <result name="invalid.token">/tokenInvalid.jsp</result>    
            </action>

    4.结果

    首先进入表单页面,提交表单

    首次提交会提交成功,提交完成之后刷新页面此时会跳转到重复页面。

    二、自定义拦截器

    自定义拦截器一般继承抽象类AbstractInterceptor,该抽象类有3个方法。destroy()、init()、intercept(ActionInvocation arg0),最主要的是intercept(ActionInvocation arg0)方法。

    Init方法在拦截器类被创建之后,在对Action镜像拦截之前调用,相当于一个post-constructor方法,使用这个方法可以给拦截器类做必要的初始话操作。

    Destroy方法在拦截器被垃圾回收之前调用,用来回收init方法初始化的资源。

    Intercept是拦截器的主要拦截方法,如果需要调用后续的Action或者拦截器,只需要在该方法中调用invocation.invoke()方法即可,在该方法调用的前后可以插入Action调用前后拦截器需要做的方法。如果不需要调用后续的方法,则返回一个String类型的对象即可。

    下面的列子是对Action进行拦截判断是否有session,如果有则判断登录成功,没有则未登录。首先创建拦截器。

    package com.cyw.test;
    
    import java.util.Map;
    
    import javax.servlet.http.*;
    
    import org.apache.struts2.ServletActionContext;
    
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
    
    public class MyInterceptor extends   AbstractInterceptor{
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
    
        @Override
        public void destroy() {
            System.out.println("MyInterceptor Destroy");
            super.destroy();
        }
    
        @Override
        public void init() {
            System.out.println("MyInterceptor init");
            super.init();
        }
    
        @Override
        public String intercept(ActionInvocation arg0) throws Exception {
            
            Map<String,Object> maps=arg0.getInvocationContext().getSession();
            String sessionName=(String)maps.get("userName");
            if(sessionName==null)
            {
                return "notlogin";
            }
            else
            {
                return arg0.invoke();
            }
            
        }
    
    }
    View Code

    然后创建了2个Action,一个登录一个登录后的。

    package com.cyw.test;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    public class LoginAction extends ActionSupport {
    
        @Override
        public String execute() throws Exception {
            return "regist";
        }
    
    }
    View Code
    package com.cyw.test;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    public class IndexAction extends ActionSupport {
        @Override
        public String execute() throws Exception {
            return "success";
        }
    }
    View Code

    在struts2.xml中注入拦截器。

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
    <struts>
    <package name="default" namespace="" extends="struts-default">
            <interceptors>
            <!-- login拦截器 -->
            <interceptor name="loginInterceptor" class="com.cyw.test.MyInterceptor"/>
            <interceptor-stack name="myInterceptorStack">
              <interceptor-ref name="basicStack"></interceptor-ref>
              <interceptor-ref name="defaultStack"></interceptor-ref>
              <interceptor-ref name="loginInterceptor"/>
            </interceptor-stack>
            </interceptors>
            <global-results>
                <result name="notlogin">/notlogin.jsp</result>
            </global-results>
            <action name="login"  class="com.cyw.test.LoginAction">
                <result name="regist">/register.jsp</result>
            </action>
            <action name="index"  class="com.cyw.test.IndexAction">
             <interceptor-ref name="myInterceptorStack"></interceptor-ref>
                <result name="success">/success.jsp</result>
            </action>
        </package>
    </struts>

    上面的xml中定义了一个拦截器栈,然后再Action中引用它,也可以在每个Action中一个一个的引入拦截器,同时可以使用<param>来对拦截器进行初始化参数。

    实验结果:

    由于对indexAction进行了拦截,所以判断session是否存在不存在跳转到notlogin.jsp页面。

    三、拦截器与过滤器的比较

    1、filter基于filter接口中的doFilter回调函数,interceptor则基于Java本身的反射机制;   
    2、filter是依赖于servlet容器的,没有servlet容器就无法回调doFilter方法,而interceptor与servlet无关;   
    3、filter的过滤范围比interceptor大,filter除了过滤请求外通过通配符可以保护页面、图片、文件等,而interceptor只能过滤请求,只对action起作用,在action之前开始,在action完成后结束(如被拦截,不执行action);   
    4、filter的过滤一般在加载的时候在init方法声明,而interceptor可以通过在xml声明是guest请求还是user请求来辨别是否过滤;   
    5、interceptor可以访问action上下文、值栈里的对象,而filter不能;   
    6、在action的生命周期中,拦截器可以被多次调用,而过滤器只能在容器初始化时被调用一次。

  • 相关阅读:
    jquery ajax跨域取数据
    Python编写相关注意事项
    深入理解java.lang.String
    Java设计模式----迭代器模式
    Java设计模式----状态模式
    Java设计模式----观察者模式
    Java设计模式----适配器模式
    Java设计模式----外观模式
    Java设计模式----建造者模式
    Java设计模式----模板方法模式
  • 原文地址:https://www.cnblogs.com/5ishare/p/6658962.html
Copyright © 2011-2022 走看看