`
peonyzzdx
  • 浏览: 590623 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

struts2 -- interceptor 拦截器

    博客分类:
  • J2EE
 
阅读更多
一、理解Struts2拦截器
1. Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP的一种实现.
2. 拦截器栈(Interceptor Stack)。Struts2拦截器栈就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被调用。
二、实现Struts2拦截器原理
Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器
三、定义Struts2拦截器。
Struts2规定用户自定义拦截器必须实现com.opensymphony.xwork2.interceptor.Interceptor接口。该接口声明了3个方法,
void init();
void destroy();
String intercept(ActionInvocation invocation) throws Exception;
其中,init和destroy方法会在程序开始和结束时各执行一遍,不管使用了该拦截器与否,只要在struts.xml中声明了该Struts2拦截器就会被执行。
intercept方法就是拦截的主体了,每次拦截器生效时都会执行其中的逻辑。

不过,struts中又提供了几个抽象类来简化这一步骤。
public abstract class AbstractInterceptor implements Interceptor;
public abstract class MethodFilterInterceptor extends AbstractInterceptor;
都是模板方法实现的。
其中AbstractInterceptor提供了init()和destroy()的空实现,使用时只需要覆盖intercept()方法;
而MethodFilterInterceptor则提供了includeMethods和excludeMethods两个属性,用来过滤执行该过滤器的action的方法。可以通过param来加入或者排除需要过滤的方法。



1.interceptor的配置

拦截器的使用:1.先定义;2.在引用使用;

//定义拦截器
<interceptor name="myInterceptor" class="com.zzz.struts2.interceptor.MyInterceptor">

//引用使用
<interceptor-ref name="myInterceptor">
              </interceptor-ref>

各种引用使用如下图:



方法1. 普通配置法

<struts>
    <package name="struts2" extends="struts-default">
        <interceptors>
            <interceptor name="myInterceptor" class="edu.hust.interceptor.MyInterceptor"></interceptor>
        </interceptors>
        <action name="register" class="edu.hust.action.RegisterAction">

            <!-- 在自定义interceptor并将其ref时, 系统会覆盖掉默认的interceptor-stack(defaultStack), 为了保证系统默认的defaultStack不受影响, 我们需要显式的将其引入 -->
            <!-- 注意两个interceptor-ref的顺序, 顺序不同, 执行效果也不同: 先配置的先执行/后配置的先退出(先进后出) -->
            <interceptor-ref name="defaultStack"></interceptor-ref>
            <interceptor-ref name="myInterceptor"></interceptor-ref>
            <result name="input">/register.jsp</result>
            <result>/result.jsp</result>          
        </action>
    </package>
</struts>



[size=medium]
注意:
<package name="struts-shop" extends="struts-default">
    <interceptors>
      <interceptor-stack name="myStack">
        <interceptor-ref name="checkbox">
          <param name="uncheckedValue">0</param>
       </interceptor-ref>
       [color=red]<interceptor-ref name="defaultStack"/> </interceptor-stack>[/color]
    </interceptors>
    <default-interceptor-ref name="myStack"/>(这句是设置所有Action自动调用的拦截器堆栈)
  </package>


<interceptor-ref name="defaultStack"/> </interceptor-stack>
在拦截器站中引用,或者在action中引用,必须得有,否则出错



方法2. 配置拦截器栈(即将多个interceptor串联的一种元素)。然后在<action>中引入该拦截器栈就可以了。[/size]

<struts>
    <package name="struts2" extends="struts-default">
        
        <interceptors>
            <interceptor name="myInterceptor" class="edu.hust.interceptor.MyInterceptor"></interceptor>
        
            <interceptor-stack name="myInterceptorStack">
                <interceptor-ref name="myInterceptor"></interceptor-ref>
                <interceptor-ref name="defaultStack"></interceptor-ref>
            </interceptor-stack>
        </interceptors>
        
        <action name="register" class="edu.hust.action.RegisterAction">
            <result name="input">/register.jsp</result>
            <result>/result.jsp</result>
            
            <interceptor-ref name="myInterceptorStack"></interceptor-ref>
        </action>
    </package>
</struts>


方法3. 修改默认拦截器,将自定义的拦截器栈定义为struts2的默认拦截器。

<struts>
    <package name="struts2" extends="struts-default">
        
        <interceptors>
            <interceptor name="myInterceptor" class="edu.hust.interceptor.MyInterceptor"></interceptor>
            <interceptor-stack name="myInterceptorStack">
                <interceptor-ref name="myInterceptor"></interceptor-ref>
                <interceptor-ref name="defaultStack"></interceptor-ref>
            </interceptor-stack>
        </interceptors>
        <!-- 此默认interceptor是针对所有action的 -->
        <!-- 如果某个action中引入了interceptor, 则在这个action中此默认interceptor就会失效 -->
        <default-interceptor-ref name="myInterceptorStack"></default-interceptor-ref>
        
        <action name="register" class="edu.hust.action.RegisterAction">
            <result name="input">/register.jsp</result>
            <result>/result.jsp</result>
        </action>
        
    </package></struts>





拦截器接口interceptor 和抽象类AbstracctInterceptor应用


package com.interceptor;  
import com.opensymphony.xwork2.ActionInvocation;  
import com.opensymphony.xwork2.interceptor.Interceptor;  
  
public class MyInterceptor implements Interceptor{  
    private String hello;//一定要写,后面会用上  
    get和set方法  
      
    public void init() {  
       System.out.println("init");  
    }  
      
    public String intercept(ActionInvocation invoker) throws Exception {  
       System.out.println("intercept");  
  
       String result=invoker.invoke();  
  
       return result;  
    }  
      
    public void destroy() {  
       System.out.println("destory");  
    }  
}  



我们在做拦截器的时候,实现了Interceptor接口,里面有三个方法,但是一般的情况下init() 和 destroy() 方法我们用不上,最关心的就是intercept(ActionInvocation invoker){}方法,所以怎么办呢?其实,struts2给我们提供了一个简化的拦截器类:AbstractInterceptor
AbstractInterceptor 这是一个抽象的类,里面实现了 init() 和 destroy() 方法,所以只要我们继承这个类,就不用再多写这两个方法!


所有拦截器的超级接口Interceptor ,Action去实现这个接口;
Interceptor 它其中有三个方法(init(),destroy() ,interceptor()):
Init()方法:在服务器起动的时候加载一次,并且只加载一次;
Destroy()方法:当拦截器销毁时执行的方法;
Interceptor()方法:其中里边有一个参数invocation

显然intercept()方法,是添加真正执行拦截工作的代码的地方,如果我们不需要初始化和清理的操作,可以直接继承com.opensymphony.xwork2.interceptor.AbstractInterceptor类,覆盖它的intercept()方法。这个方法有个ActionInvocation类型的参数,可以用它取得Session或转发请求等操作。


示例展示

明白了原理之后还需要做几项具体的工作:
1,自己写一个拦截器,实现检查用户是否登陆的功能。
2,添加拦截器的配置,让我们自己写的拦截器起作用。


LogonInterceptor.java

package tutorial.interceptor; 
import java.util.Map; 
import org.apache.struts2.ServletActionContext; 
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor; 
/**
* 登陆验证拦截器,如果用户没有登陆系统则让用户到登陆验证页面进行登陆
* 当用户请求网站资源的时候,例如某个Action,在Action被执行之前,检
* 查用户是否登陆了系统.
* 不足之处是该拦截器只能拦截Action,不能拦截jsp和servlet,所以不能
* 完全限制用户对未授权资源的访问,可以配合filter或将jsp页面放在
* WEB-INF目录下解决这个问题.
* 
* @author coombe
*/
public class LogonInterceptor extends AbstractInterceptor { 
      public String intercept(ActionInvocation invocation) throws Exception {
          // 取得请求的Action名
          String    name = invocation.getInvocationContext().getName();
  
          if (name.equals("Login")) {
              // 如果用户想登录,则使之通过
              return invocation.invoke(); 
          } else {
              // 取得Session。
              ActionContext ac = invocation.getInvocationContext();
              Map session =    (Map)ac.get(ServletActionContext.SESSION);
   
              if (session == null) {
                  // 如果Session为空,则让用户登陆。
                  return "login";
              } else {
                  String username = (String)session.get("username");
                  if (username == null) {
                      // Session不为空,但Session中没有用户信息,
                      // 则让用户登陆
                      return "login";
                  } else {
                      // 用户已经登陆,放行~
                      return invocation.invoke(); 
                  }
              }
          }
      }
} 


/*1,自定义拦截器
2,重定义默认拦截器堆栈
3,添加一个global-results,用户在验证失败的情况下跳转到登陆验证页面
*/


struts.xml

<!DOCTYPE struts PUBLIC
      "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
      "http://struts.apache.org/dtds/struts-2.0.dtd"> 
<struts><!-- Configuration for the default package. -->
<constant name="struts.custom.i18n.resources" value="globalMessages" />

<include file="struts-validation.xml" /> 
<package name="default" extends="struts-default">
  
    <!-- 自定义拦截器 -->
    <interceptors>
     <interceptor name="logon" class="tutorial.interceptor.LogonInterceptor"/>
        <!-- 自定义拦截器堆栈 -->
        <interceptor-stack name="myStack">
        <interceptor-ref name="logon"/>
        <!-- 引用默认的拦截器堆栈
      如果不用defaultStack,则表单值将会被页面跳转后返回-->
        <interceptor-ref name="defaultStack"/>
     </interceptor-stack>
    </interceptors>
  
    <!-- 重定义默认拦截器堆栈 -->
    <default-interceptor-ref name="myStack"/>
  
    <global-results>
     <result name="login" type="redirect-action">Login!input.action</result>
    </global-results>
  
        <action name="HelloWorld" class="tutorial.HelloWorld">
               <result>/HelloWorld.jsp</result>
           </action>
         
           <action name="Login" class="tutorial.Login">
              <result>/Success.jsp</result>
              <result name="input">/Login.jsp</result>
           </action>  
</package>
</struts> 


方法过滤拦截器MethodFilterInterceptor

1:上边的拦截器都要是针对整个action的,如果针对某个方法进行拦截可以去继承这个类;

它的使用跟上边的使用方法差不多,只是需要要配置它对那个方法进行拦截,方法过滤拦截器最好不要配置到自己设置默认的拦截器栈里边,自己手动配置.


<interceptor-ref name="myInterceptor3">
              <param name="includeMethods">execute</param>
              <param name="excludeMethods">execute</param>
             </interceptor-ref>
           <interceptor-ref name="defaultStack"></interceptor-ref>


其中includeMethods ,excludeMethods是固定写法: includeMethods 包含拦截那些方法,多个方法需要用”,”隔开; excludeMehtods是排除拦截的那些方法;



拦截器添加参数

MyInterceptor.java


package com.interceptor;  
import com.opensymphony.xwork2.ActionInvocation;  
import com.opensymphony.xwork2.interceptor.Interceptor;  
  
public class MyInterceptor implements Interceptor{  
    private String hello;//一定要写,后面会用上  
    get和set方法  
      
    public void init() {  
       System.out.println("init");  
    }  
      
    public String intercept(ActionInvocation invoker) throws Exception {  
       System.out.println("intercept");  
  
       String result=invoker.invoke();  
  
       return result;  
    }  
      
    public void destroy() {  
       System.out.println("destory");  
    }  
}  

private String hello;    get和set方法
写个变量,然后加上get和set方法,当然变量的名字必须和设定的参数是相同的,这个是赋值成功的前提条件
 
可以通过以下两种方式添加参数
1. 定义拦截器的时候添加参数:
Xml代码 

<interceptor name="myinterceptor" class="com.interceptor.MyInterceptor">  
    <param name="hello">world</param>  
</interceptor>  

2. 使用拦截器的时候添加参数:
Xml代码 

<interceptor-ref name="myinterceptor">  
     <param name="hello">zhuxinyu</param>  
</interceptor-ref>
 

可是还有个问题,在定义的时候添加了参数hello,使用时同样添加了参数param,当运行MyInterceptor类时会输出哪个呢? world 还是 zhuxinyu。
结果是:zhuxinyu  很明显,覆盖了第一个,这是什么原则:就近原则。形如 OO 中的覆盖,重写


此时,运行MyInterceptor.java,在整个拦截器中任何方法中运行 System.out.println(hello);成功输出: world




Struts2拦截器的执行顺序

1.如果一个系统中配置了多个拦截器,根据拦截器配置的顺序不同,执行拦截器的顺序也不一样。通常认为,先配置的拦截器,会先获得执行的机会,但是实际情况不是这样。execute()方法执行之前,配置在前面的拦截器,会先对用户的请求起作用。execute()方法执行之后,配置在后面的拦截器,会先对用户的请求起作用。(两头向中间靠拢的执行)

定义拦截器
Java代码 

package com.sh.interceptor;  
  
import com.opensymphony.xwork2.ActionInvocation;  
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;  
  
public class DefaultInterceptor extends AbstractInterceptor{  
  
    private String name;  
      
    public void setName(String name) {  
        this.name = name;  
    }  
  
    @Override  
    public String intercept(ActionInvocation invocation) throws Exception {  
        System.out.println(name+"执行了。。。");  
        String result=invocation.invoke();  
        System.out.println(name+"执行完毕。。。");  
        return result;  
    }  
      
}  


action
Java代码 

package com.sh.action;  
  
import com.opensymphony.xwork2.ActionSupport;  
  
public class DefaultAction extends ActionSupport {  
    public String execute(){  
        return SUCCESS;  
    }  
}  


struts.xml
Xml代码

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE struts PUBLIC  
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"  
    "http://struts.apache.org/dtds/struts-2.3.dtd">  
  
<struts>   
    <!-- 如果 注解的action配置改变时候不需要重新启动tomcate -->  
    <constant name="struts.devMode" value="false"/>    
    <constant name="struts.convention.classes.reload" value="true" />   
      
    <package name="default" extends="struts-default">  
        <interceptors>  
            <interceptor name="inter1" class="com.sh.interceptor.DefaultInterceptor"/>  
            <interceptor name="inter2" class="com.sh.interceptor.DefaultInterceptor"/>  
            <interceptor name="inter3" class="com.sh.interceptor.DefaultInterceptor"/>  
        </interceptors>  
        <action name="default" class="com.sh.action.DefaultAction">  
            <result>/index.jsp</result>  
            <interceptor-ref name="inter1">  
                <param name="name">拦截器1</param>  
            </interceptor-ref>  
            <interceptor-ref name="inter2">  
                <param name="name">拦截器2</param>  
            </interceptor-ref>  
            <interceptor-ref name="inter3">  
                <param name="name">拦截器3</param>  
            </interceptor-ref>  
            <interceptor-ref name="defaultStack"/>  
        </action>  
      
    </package>  
      
</struts>  


--访问
http://localhost:8080/Struts2_interceptorSort/default.action

--控制台的信息 如下
拦截器1执行了。。。
拦截器2执行了。。。
拦截器3执行了。。。
拦截器3执行完毕。。。
拦截器2执行完毕。。。
拦截器1执行完毕。。。

[/size]
  • 大小: 8.6 KB
分享到:
评论

相关推荐

    Struts2拦截器(Interceptor)

    Struts2拦截器(Interceptor) Struts2拦截器(Interceptor)

    struts2--4.拦截器

    在Struts2中,拦截器扮演着核心角色,极大地增强了框架的功能和灵活性。本文将深入探讨Struts2中的拦截器,以及如何使用它们来优化应用的性能和功能。 ### 1. 拦截器的概念 拦截器是Struts2框架的一个关键特性,它...

    struts2-core-2.0.11源码

    在`org.apache.struts2.interceptor`包下,你可以找到各种预定义的拦截器类。 2. **配置管理(Configuration Manager)**:Struts2通过`org.apache.struts2.config`包中的类来管理配置信息,包括XML配置文件和注解...

    struts2 Interceptor拦截器

    ### Struts2 Interceptor 拦截器详解 #### 一、概述 在现代Web开发中,特别是基于Java的Web应用程序开发中,Struts2框架因其简洁性和强大的扩展能力而备受青睐。Struts2框架的核心设计理念之一是MVC(Model-View-...

    Struts2-2.5.13最新jar下载

    2. **Interceptor**:拦截器是Struts2的一个重要特性,它们是插件式的,可以插入到Action调用流程中,实现如日志、权限检查、事务管理等通用功能。 3. **Result**:结果是Action执行后返回的对象,通常用于渲染视图...

    spring-mybatis-struts2-master ——demo

    3. 配置Struts2:配置struts.xml,定义Action及其结果,设置拦截器栈。 4. 配置MyBatis:创建mybatis-config.xml,定义数据源、事务工厂,以及Mapper接口和XML映射文件的路径。 5. 创建实体类、Mapper接口和XML映射...

    struts2-core-2.3.7源码

    3. **Interceptor(拦截器)**: 拦截器是Struts2的核心特性,它们按照预设的顺序执行,可以在Action执行前后进行额外的操作,如日志记录、权限检查等。 4. **Value Stack**: 用于存储Action实例和其他Action上下文...

    Struts2 拦截器 Interceptor

    ### Struts2 拦截器 Interceptor #### 一、概述 在Struts2框架中,拦截器(Interceptor)是一种非常重要的机制,它能够帮助开发者实现诸如权限控制、事务管理、日志记录等跨切关注点的功能。通过定义不同的拦截器...

    struts2-tags-文档.rar

    "struts2.chm"可能是Struts2的基础教程,涵盖了框架的基本概念、配置、动作、拦截器等核心组件。在这个文档中,你可以了解到如何设置Struts2的配置文件,如何创建Action类,以及如何使用拦截器进行业务逻辑处理。...

    struts2-core-2.2.1 jar下载、源码下载 非常全面!!绝对可用!! 所需资源分最少。

    Struts2的核心组件是`struts2-core.jar`,这个文件是整个框架的基础,包含了处理请求、调度、拦截器等核心功能。`struts2-core-2.2.1`版本是Struts2的一个特定发行版,可能包含了一些特定的改进和修复。 在Java Web...

    STRUTS2:拦截器Interceptor

    STRUTS2:拦截器Interceptor

    struts2 相关jar包 包含json-lib-2.1.jar+struts2-json-plugin-2.1.8.1.jar

    - **Interceptor(拦截器)**:这些是Struts2中的重要组件,它们在Action调用前后执行,提供了事务控制、日志记录、权限验证等功能。 - **配置文件**:通常有struts.xml或类似的配置文件,用于定义Action、结果...

    struts-2.5.22-all.zip

    Struts2框架的优势在于其强大的拦截器(Interceptor)机制,允许开发者定义自定义的行为,如日志记录、权限检查等,可以在请求处理流程中的不同阶段插入。此外,它还支持多种结果类型,如Redirect、Stream等,方便...

    struts2-2.3.4.1-all

    2. **拦截器(Interceptor)**:这是Struts2的一个强大特性,它可以拦截Action调用前后,实现事务管理、日志记录、权限验证等功能。通过配置拦截器栈,开发者可以灵活控制请求处理流程。 3. **OGNL(Object-Graph ...

    struts2-2.0.14

    此外,还包括了Interceptor(拦截器)机制,这是一种AOP(面向切面编程)的实现,允许在Action执行前后插入自定义代码,用于日志记录、权限验证等通用功能。Struts2核心库还支持OGNL(Object-Graph Navigation ...

    struts2-blank-2.0.14的lib中的jar包

    3. **拦截器库** - `struts2-dojo-plugin.jar`: 提供了与Dojo JavaScript库的集成,支持富客户端界面的创建。 - `struts2-json-plugin.jar`: 支持JSON数据格式的输入输出,方便进行AJAX交互。 - `struts2-spring-...

    Struts2--自定义拦截器

    自定义拦截器是Struts2中的一个重要特性,允许我们扩展框架的功能,以实现诸如日志记录、权限检查、性能监控等通用任务。在本文中,我们将深入探讨如何创建和使用自定义拦截器。 首先,了解拦截器的基本概念。在...

    struts2-blank

    Action是业务逻辑的执行者,Interceptor是拦截器,用于在Action执行前后进行额外的操作,如日志记录、权限检查等。Result则是Action执行后返回的结果,它可以是JSP、FreeMarker模板或其他类型的视图。ValueStack则是...

    struts2-拦截器.docx

    当一个HTTP请求到达Struts2的ServletDispatcher时,框架会根据配置文件(如struts.xml)来实例化相应的拦截器对象,并将它们组成一个拦截器链(Interceptor Chain或Interceptor Stack)。这个链中,每个拦截器按照预...

    struts2-core-2.3.32和xwork-core-2.3.32

    XWork的拦截器(Interceptor)机制在Struts2中扮演了关键角色,允许开发者定义一系列在Action执行前后运行的代码片段,用于日志记录、权限检查、数据校验等操作。 Struts2的MVC设计模式使得开发者可以清晰地分离...

Global site tag (gtag.js) - Google Analytics