一、Struts2拦截器原理:

Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的    拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器。

比如:应用要求用户登陆,且必须为指定用户名才可以查看系统中某个视图资源;否则,系统直接转入登陆页面。对于上面的需求,可以在每个Action的执行实际处理逻辑之前,先执行权限检查逻辑,但这种做法不利于代码复用。因为大部分Action里的权限检查代码都大同小异,故将这些权限检查的逻辑放在拦截器中进行将会更加优雅。

PS:

1. Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP的一种实现.

2. 拦截器栈(Interceptor Stack)。Struts2拦截器栈就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被调用。

二、Struts2 拦截器接口实现:

Struts2规定用户自定义拦截器必须实现com.opensymphony.xwork2.interceptor.Interceptor接口。该接口声明了3个方法,其中,init和destroy方法会在程序开始和结束时各执行一遍,不管使用了该拦截器与否,只要在struts.xml中声明了该Struts2拦截器就会被执行。intercept方法就是拦截的主体了,每次拦截器生效时都会执行其中的逻辑。

void init();

void destroy();

String intercept(ActionInvocation invocation) throws Exception;

1:所有拦截器都使用接口Interceptor ,Action去实现这个接口;

Init()方法:在服务器起动的时候加载一次,并且只加载一次;

Destroy()方法:当拦截器销毁时执行的方法;

Interceptor()方法:其中里边有一个参数invocation;

public String intercept(ActionInvocation invocation) throws xception {

System.out.println("interceptor!!");

String result=invocation.invoke();

return result;

}

其中intercept方法是拦截器的核心方法,所有安装的拦截器都会调用之个方法。在Struts2中已经在struts-default.xml中预定义了一些自带的拦截器,如timer、params等。如果在<package>标签中继承struts-default,则当前package就会自动拥有struts-default.xml中的所有配置。

Invocation.invoke()是如果只有一个拦截器执行完这个方法后,会返回给视图,如果有多个拦截器,它顺序的执行完所有的拦截器,才返回给视图,也就是调用后面的action继续执行。

二、Struts2 拦截器详细配置:

默认拦截器是在不设置任何拦截器的时候,给予默认设置的,当只要设置任何一个拦截器就会覆盖掉默认拦截器, 故此,我们需要手动设置

一旦实现了检查拦截器,就可以在所有需要实现权限控制的Action中复用上面的拦截器。

为了使用该拦截器,首先在struts.xml文件中定义拦截器,定义拦截器的配置片段如下:

<!-- 用户拦截器定义在该元素下 -->

<interceptors>

<!-- 定义了一个名为authority的拦截器 -->

<interceptor name="authority" class="lee.AuthorityInterceptor"/>

</interceptors>

定义了该拦截器之后,可以在Action中应用该拦截器,应用该拦截器的配置片段如下:

<!-- 定义一个名为viewBook的Action,其实现类为ActionSupport -->

<action name="viewBook">

<!-- 返回success视图名时,转入/WEB-INF/jsp/viewBook.jsp页面 -->

<result>/WEB-INF/jsp/viewBook.jsp</result>

<!-- 拦截器一般配置在result元素之后! -->

<interceptor-ref name="defaultStack"/>

<!-- 应用自定义拦截器 -->

<interceptor-ref name="authority"/>

</action>

上面名为viewBook的Action,没有指定class属性,默认使用ActionSupport类,配置该Action时,只是指定了一个Result,指定返回success字符串时,系统将转入/WEBINF/jsp/viewBook.jsp页面。但并为未配置login视图对应的JSP页面。

考虑到这个拦截器的重复使用,可能在多个Action都需要跳转到login逻辑试图,故将login Result定义成一个全局Result。下面是配置login Result的配置片段:

<!-- 定义全局Result -->

<global-results>

<!-- 当返回login视图名时,转入/login.jsp页面 -->

<result name="login">/login.jsp</result>

</global-results>

经过上面的配置,如果浏览者在浏览器中直接发送viewBook请求,将会转入如图所示的页面。

这种通过拦截器进行权限控制的方式,显然具有更好的代码复用。

如果为了简化struts.xml文件的配置,避免在每个Action中重复配置该拦截器,可以将该拦截器配置成一个默认拦截器栈(这个默认拦截器栈应该包括default-stack拦截器栈和权限检查拦截器)。

定义自己的默认拦截器栈的配置片段如下:

<interceptors>

<!-- 定义权限检查拦截器 -->

<interceptor name="authority" class="lee.AuthorityInterceptor"/>

<!-- 定义一个包含权限检查的拦截器栈 -->

<interceptor-stack name="mydefault">

<!-- 定义拦截器栈包含default-stack拦截器栈 -->

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

<!-- 定义拦截器栈包含authority拦截器 -->

<interceptor-ref name=" authority"/>

</interceptor- stack >

</interceptors>

一旦定义了上面的mydefault拦截器栈,这个拦截器栈包含了权限检查拦截器和系统默认的拦截器栈。如果将这个拦截器栈定义成默认拦截器,则可以避免在每个Action需要重复定义权限检查拦截器。

下面是定义默认拦截器的配置片段:

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

一旦在某个包下定义了上面的默认拦截器栈,在该包下的所有Action都会自动增加权限检查功能。对于那些不需要使用权限控制的Action,将它们定义在另外的包中——这个包中依然使用系统原来的默认拦截器栈,将不会有权限控制功能。

PS:拦截器,拦截器栈和默认的拦截器之间的关系

1:拦截器和拦截器栈是一个级别的,也就是说一个拦截器栈中包括许多拦截器, 一个拦截器栈中还可以包括许多拦截器栈,配置如下方式:

<interceptors>

<!-- 先定义拦截器 -->

<interceptor name="myInterceptor" class="com.struts2.interceptor.MyInterceptor">

<!-- 指定系统初始化给拦截器的参数 -->

<param name="hello">张--</param>

</interceptor>

<!-- 加到自己设置的拦截器栈里边去 -->

<interceptor-stack name="myStack">

<interceptor-ref name="myInterceptor">

</interceptor-ref>

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

</interceptor-stack>

</interceptors>

拦截器的使用:

1.先定义;

2.在引用使用;

<interceptor name="myInterceptor" class="com.struts2.interceptor.MyInterceptor">

<interceptor-ref name="myInterceptor">

</interceptor-ref>

2:struts2中有一个系统默认的拦截器栈是 defaultStack,如果你手动引用自己的拦截器,系统默认的拦截器栈将不起作用;这样必需手动引入系统的拦截器栈<interceptor-ref name="defaultStack">

</interceptor-ref>

如果想改变系统默认的拦截器栈,可以这样配置:

<default-interceptor-ref name="myStack">

</default-interceptor-ref>其中myStack是自己定义的拦截器栈名字;

如果拦截器栈中有多个拦截器,在执行action之前的顺序跟配置拦截器的顺序一致,而在action之后执行的顺序是相反的;

PS:最后还附加一点过滤器的东西

过滤器,是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符

拦截器,是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。

拦截器与过滤器的区别 :

1、拦截器是基于java的反射机制的,而过滤器是基于函数回调。

2、拦截器不依赖与servlet容器,过滤器依赖与servlet容器。

3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。

4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。

5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次

6、执行顺序 :过滤前 - 拦截前 - Action处理 - 拦截后 - 过滤后。

过滤是一个横向的过程,首先把客户端提交的内容进行过滤(例如未登录用户不能访问内部页面的处理);过滤通过后,拦截器将检查用户提交数据的验证,做一些前期的数据处理,接着把处理后的数据发给对应的Action;Action处理完成返回后,拦截器还可以做其他过程(还没想到要做啥),再向上返回到过滤器的后续操作。

一个Filter 可负责拦截多个请求或响应:一个请求或响应也可被多个请求拦截。

创建一个Filter 只需两个步骤:

(1)创建Filter 处理类:

(2)在web.xml 文件中配置Filter 。

创建Filter 必须实现javax.servlet.Filter 接口,在该接口中定义了三个方法。

• void init(FilterConfig config): 用于完成Filter 的初始化。

• void destroy(): 用于Filter 销毁前,完成某些资源的回收。

• void doFilter(ServletRequest request, ServletResponse response,FilterChain chain): 实现过滤功能,该方法就是对每个请求及响应增加的额外处理。

过滤器Filter也具有生命周期:init()->doFilter()->destroy(),由部署文件中的filter元素驱动。在servlet2.4中,过滤器同样可以用于请求分派器,但须在web.xml中声明,<dispatcher>INCLUDE或FORWARD或REQUEST或ERROR</dispatcher>该元素位于filter-mapping中。

Struts2拦截器详解的更多相关文章

  1. Struts2 之 modelDriven & prepare 拦截器详解

    struts2 ModelDriven & Prepareable 拦截器 前面对于 Struts2 的开发环境的搭建.配置文件以及 Struts2 的值栈都已经进行过叙述了!这次博文我们讲解 ...

  2. struts2 18拦截器详解(七)

    ChainingInterceptor 该拦截器处于defaultStack第六的位置,其主要功能是复制值栈(ValueStack)中的所有对象的所有属性到当前正在执行的Action中,如果说Valu ...

  3. struts2 18拦截器详解(十)

    ModelDrivenInterceptor 该拦截器处于defaultStack中的第九的位置,在ScopedModelDrivenInterceptor拦截器之后,要使该拦截器有效的话,Actio ...

  4. struts2 18拦截器详解(九)

    ScopedModelDrivenInterceptor 该拦截器处于defaultStack第八的位置,其主要功能是从指定的作用域内检索相应的model设置到Action中,该类中有三个相关的属性: ...

  5. struts2 18拦截器详解(五)

    I18nInterceptor 该拦截器处理defaultStack第四的位置,是用来方便国际化的,如果说我们的一个Web项目要支持国际化的话,通常的做法是给定一个下拉框列出所支持的语言,当用户选择了 ...

  6. struts2内置拦截器和自定义拦截器详解(附源码)

    一.Struts2内置拦截器 Struts2中内置类许多的拦截器,它们提供了许多Struts2的核心功能和可选的高级特 性.这些内置的拦截器在struts-default.xml中配置.只有配置了拦截 ...

  7. 通俗易懂之SpringMVC&Struts2前端拦截器详解

    直接进入主题吧!一,配置Struts2的拦截器分两步走1配置对应的拦截器类:2在配置文件Struts.xml中进行配置拦截器同时在Strust2中配置拦截器类有三种方法1实现Interceptor接口 ...

  8. Struts2中的拦截器详解

    exception:异常拦截器,拦截异常aliasservletConfig18nprepare:预备拦截器,这个拦截器就是为了ModelDriven准备对象的,若Action类实现了preparab ...

  9. [转]SpringMVC拦截器详解[附带源码分析]

      目录 前言 重要接口及类介绍 源码分析 拦截器的配置 编写自定义的拦截器 总结 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:ht ...

随机推荐

  1. Qt ------ 自定义QVector<T>中的T

    #ifndef FREQUENCYSPECTRUM_H #define FREQUENCYSPECTRUM_H #include <QtCore/QVector> /** * Repres ...

  2. 让外部网络访问K8S service的四种方式

    本文基于kubernetes 1.5.2版本编写 kube-proxy+ClusterIP kubernetes版本大于或者等于1.2时,配置: 修改master的/etc/kubernetes/pr ...

  3. Access时间日期函数大全

    这里特别推荐WeekdayName() 函数.MonthName() 函数,将日期转换为中文星期名与月份,如"星期一"."五月"一.Date() 函数.Now( ...

  4. Java基础-Java中的并法库之线程池技术

    Java基础-Java中的并法库之线程池技术 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是线程池技术 二.

  5. 为ASP.NET控件加入快捷菜单

    ContextMenu Control 快捷菜单控件概述: MSDN Liabrary 中包含了几个DHTML快捷菜单的示例.分别提供了对这一功能的不能实现方法.一个快捷菜单就是在页面中任何位置的一组 ...

  6. 20155203 2016-2017-2 《Java程序设计》第7周学习总结

    20155203 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 1.Lambda表达式.(使用interface函数接口) 2.Lambda的方法参考Met ...

  7. OE中的bitbake使用

    OpenEmbedded是一些脚本(shell和python脚本)和数据构成的自动构建系统.     脚本实现构建过程,包括下载(fetch).解包(unpack).打补丁(patch).config ...

  8. jquery easyui:tab自动加载第一个tab内容

    $('#resourceTabs').tabs('unselect', 0);$('#resourceTabs').tabs('select', 0);

  9. Android方法引用数超过65535优雅解决

    随着应用不断迭代更新,业务线的扩展,应用越来越大(比如:集成了各种第三方SDK或者公共开源的Library文件.jar文件)这样一来,项目耦合性就很高,重复作用的类就越来越多了,SO:问题就来了.相信 ...

  10. spring-service.xml 模板

    ssm模板 <?xml version="1.0" encoding="UTF-8"?>  <beans xmlns="http:/ ...