Struts 2 拦截器

时间:2023-11-22 16:10:08

什么是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()方法。

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

Struts 2 拦截器

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>

自定义拦截器

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

Struts 2 拦截器

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

Struts 2 拦截器

关于页面的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文件中对拦截器进行如下配置:

Struts 2 拦截器

相关文章