zoukankan      html  css  js  c++  java
  • Struts 2 拦截器

    什么是Struts 2 拦截器

     拦截器就是当用户请求后台Action类时在Action的Excute()方法执行前和Result返回魔板试图之后(将页面(数据)发送给浏览器渲染之前)所需要的一些通用操作存放在拦截器中对数据进行拦截!

    简单来说就是对请求和响应信息进行过滤,可以看做是Java EE中的过滤器,但是需要注意的是拦截器只能对Action类的请求进行拦截若直接请求jsp文件、Css样式等静态文件拦截器是无法进行过滤的!

    为什么要使用拦截器

    任何优秀的MVC框架都会提供一些通用的操作,如请求数据的封装、类型转换、数据校验、解析上传的表单、防止表单的多次提交等。而早期的MVC框架中,这些通用的操作都写死在核心控制器中,然而并不是所用的请求都需要这些操作的实现,于是就导致了框架的灵活性差、可扩展性低等问题。

    Struts2将它的核心功能放到拦截器而不是集中在核心控制器中实现,把大部分控制器需要完成的工作按功能分开定义,每个拦截器只完成一个功能,而完成这些功能的拦截器可以自由选择,灵活组合,需要哪些功能只需要在配置文件中进行添加即可,从而提高了框架的灵活性。

    拦截器的工作原理

    Struts2拦截器围绕Action和Result的执行而执行。其实现原理和Servlet Filter差不多,以链式执行,对真正要执行的方法(execute())进行拦截。首先执行Action配置的拦截器,在Action和Result执行之后,拦截器在一次执行(与先前的执行顺序相反),在此以链式的执行过程中,任何一个拦截器都可以直接返回,从而终止余下的拦截器、Action及Result的执行。

    当ActionInvocation的invoke()方法被调用时,开始执行Action配置的第一个拦截器,拦截器作出相应的处理后会在此调用ActionInvocation的invoke()方法,ActionInvocation对象负责跟踪执行过程的状态,并且把控制权交给合适的拦截器。ActionInvocation通过调用拦截器的intercept()方法将控制转交给拦截器。因此,拦截器的执行过程可以看做是一个递归的过程,后续拦截器继续执行,直到最后一个拦截器,invoke()方法会执行Action的execut()方法。

    先面以一张图来描述拦截器的执行过程

    image

    Struts2的内值拦截器

    Struts2提供了一些默认的内值拦截器。如下所示:

    <!--拦截器栈(可以存放一堆拦截器,在调用时只需调用defaultStack就可以调用其中的所有拦截器)-->  
    <interceptor-stack name="defaultStack">
                    <interceptor-ref name="exception"/><!--用于捕获异常,并根据类型将异常映射到用户自定义的错误页面-->
                    <interceptor-ref name="alias"/>
                    <interceptor-ref name="servletConfig"/><!--将源于Servlet API的各种对象注入 Action当中-->
                    <interceptor-ref name="i18n"/>
                    <interceptor-ref name="prepare"/>
                    <interceptor-ref name="chain"/>
                    <interceptor-ref name="scopedModelDriven"/>
                    <interceptor-ref name="modelDriven"/>
                    <interceptor-ref name="fileUpload"/><!--将文件和元数据从多重请求转换为常规的请求数据,以便能将他们设置在队形的Action属性中-->
                    <interceptor-ref name="checkbox"/>
                    <interceptor-ref name="datetime"/>
                    <interceptor-ref name="multiselect"/>
                    <interceptor-ref name="staticParams"/><!--将在配置文件中通过action的子元素param设置的参数设置到对应的Action属性中-->
                    <interceptor-ref name="actionMappingParams"/>
                    <interceptor-ref name="params"/><!--将请求中的数据设置到Action中的属性上-->
                    <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-ref name="deprecation"/>
                </interceptor-stack>

    自定义拦截器

    介绍了那么多的原理,现在我们来自己编写一个拦截器来体验一下吧。下面来说一下我们这个例子的功能。首先当用户访问我们的网站时使用拦截器判断其是否已经登录,如果没有登录则跳转到登录页面进行登录如图所示:

    image

    如果是已经登录的用户则直接跳转到欢迎界面,如图所示:

    image

    关于页面的html和登录的验证代码这里就不在进行展示了,我们主要看一下关于拦截器的代码,首先我们要定义一个拦截器类(该类实现com.opensymphony.xwork2.interceptor.Interceptor 接口)。其代码如下:

    package cn.wz.logindemo;

    import java.util.Map;

    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.Interceptor;

    public class Myinterceptor implements Interceptor {
        /**
         *
         */
        private static final long serialVersionUID = 1L;
        /**
         * 实现Interceptor接口的intercept()方法,该方法进行拦截操作,
         */
        public String intercept(ActionInvocation invoc) throws Exception {
            ActionContext context = invoc.getInvocationContext();//获取Action上下文对象
            Map<String, Object> map = context.getSession();//通过Action上下文获取Session对象的集合(Session实质上就是封装了一个map集合,通过getSession()方法来以解耦的方式获取Session)
            boolean falg = map.containsKey("userName");//判断用户是否已经登录
            if (falg) {
                //如果已经登录则将控制权转交给其它的拦截器或Action
                     return     invoc.invoke();
           
            }
            //如果没有登录则返回“input”不再执行其他拦截器或Action直接跳转到登录页面
        return "input";
        }
        /**
         * 实现Interceptor接口的destory()方法,该方法只在该拦截器销毁时调用一次
         */
        public void destroy() {
           
        }
        /**
         * 实现Interceptor接口的init方法,该方法只在该拦截器初始化时调用一次
         */
        public void init() {
           
        }


    }

    然后在Struts.xml文件中对拦截器进行如下配置:

    image

  • 相关阅读:
    hadoop基础
    数据库基础知识
    sqoop基础
    大数据之常用linux常用命令
    zooKeeper基础
    impala基础
    Hbase基础
    Commitlint 提交规范类型
    理解JS闭包
    JS函数作用域及作用域链理解
  • 原文地址:https://www.cnblogs.com/wangzheand/p/5842008.html
Copyright © 2011-2022 走看看