`
lanxiangbo
  • 浏览: 6177 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

[转]STRUTS2的拦截器

    博客分类:
  • SSH2
阅读更多

原文链接:http://hi.baidu.com/annleecn/blog/item/1b4931f2b7f2cb56352acca2.html

拦截器是Struts2的一个重要的组成部分,Struts2框架的拦截器是可以动态配置的,下面首先来看一个最使用JDK的反射机制实现的拦截器。

1,最简单的拦截器例子

1,业务接口,因为JDK动态代理只能对实现了接口的实例来生成代理,因此必须提供一个接口:

package com.test;

public interface Dog {
public void info();
public void run();
}

2,业务实现类:

package com.test;

public class DogImpl implements Dog {

@Override
public void info() {
   System.out.println("I'm a dog");

}

@Override
public void run() {
   System.out.println("I'm running fast");
}

}

3,用于拦截Dog实例的拦截器类:

package com.test;

//定义拦截器类
public class DogIntercepter {
public void method1(){
   System.out.println("invocate method1");
}

public void method2(){
   System.out.println("invocate method2");
}
}

4,通过反射机制,动态地调用目标对象的方法,代理类:

package com.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ProxyHandler implements InvocationHandler {

//需要被代理的目标对象
private Object target;

//创建拦截器实例
DogIntercepter di = new DogIntercepter();

@Override
public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
   Object result = null;
   //如果被调用的方法名为info,就执行拦截
   if(method.getName().equals("info")){
    //调用拦截器的方法1
    di.method1();
    result = method.invoke(target, args);
    //调用拦截器的方法2
    di.method2();

   }else{
    result = method.invoke(target, args);
   }
   return result;
}
public void setTarget(Object o){
   this.target = o;
}

}

5,代理工厂类:主要作用是根据目标对象生成一个代理对象,可以不要

package com.test;

import java.lang.reflect.Proxy;

public class MyProxyFactory {
public static Object getProxy(Object obj){
   //创建代理类
   ProxyHandler handler = new ProxyHandler();
   //把该Dog实例托付给代理操作
   handler.setTarget(obj);
   //第一个参数是用来创建动态代理的ClassLoader对象,只要该对象能访问Dog接口即可
   //第二个参数是接口数组,正是代理该接口数据
   //第三个参数是代理包含的处理实例
   return Proxy.newProxyInstance(DogImpl.class.getClassLoader(),obj.getClass().getInterfaces(),handler);
}

}

6,测试方法:

package com.test;

public class TestDog {

public static void main(String[] args) {
   //创建一个Dog实例,该实例则将被做为代理的目标对象
   Dog targetObject = new DogImpl();
   Dog dog = null;
   //以目标对象创建动态代理
   Object proxy = MyProxyFactory.getProxy(targetObject);
   if(proxy instanceof Dog){
    dog = (Dog)proxy;
   }

   //正常调用
   dog.info();
   dog.run();
}

}
在这里我并没有直接使用new生成的DogImpl对象来执行方法,而是使用了代理生成的对象来执行方法,这个方法就是拦截器和目标对象方法的组合。

这其实就是AOP编程(Aspect Orient Program面向切面编程),这里有三个重要的概念:

1,目标对象:就是最原始的业务对象

2,代理对象:以目标对象为蓝本,生成的新对象,此对象已经被拦截器所监控

3,被插入的处理方法:定义在拦截器中,会在被拦截方法之前,之后自动执行的方法

JDK的反射机制和代理机制,我在后面会有专题来进行介绍。

2,Struts2中的拦截器配置说明

1,拦截器的配置

Struts中可以配置单个拦截器,也可以几个拦截器一起配置成拦截器组,它还有一个默认的拦截器defaultStack,单个拦截器的配置如下:

<intercepter name="拦截器名" class="拦截器实现类" />

拦截器同样可以注入参数:

<intercepter name="拦截器名" class="拦截器实现类">

<param name="参数名">参数值</param>

</intercepter>

拦截器栈配置如下:

<interceptor-stack name="customStack">
     <!-- 引用STRUTS2默认拦截器 -->
     <interceptor-ref name="defaultStack"></interceptor-ref>

    <interceptor-ref name="其它拦截器名"></interceptor-ref>

</interceptor-stack>

拦截器栈里同样可以配置拦截器栈,这个配置跟拦截器一样。同样在拦截器栈中配置的拦截器也可以指定参数,这里的参数将会覆盖原来配置时的默认参数。

2,在Action中使用拦截器

定义了拦截器之后就可以使用它了,在Action内可以通过以下方式引用拦截器:

        <!-- 配置fileUpload的拦截器 -->
        <interceptor-ref name="fileUpload">

这里同样可以指定参数。

默认拦截器可以在定义一个包时就指定,它可以应用于这个包的所有的action,但是一旦一个action指定了拦截器之后就不再使用默认拦截器了,此时需要手动配置默认拦截器的使用。默认拦截器可以是自己的拦截器也可以是拦截器栈,配置如下:

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

每个包中只能指定一个默认拦截器。这里也可以配置参数,但此时的参数将取代定义拦截器时的参数。我们开发的包都继承自struts-default包,这个包里已经配置了系统的默认拦截器。

3,开发自己的拦截器

虽然Struts2提供了足够的功能强大的拦截器,但是我们也可以定义自己的拦截器来实现某些特定功能。我们只要实现com.opensymphony.xwork2.intercepter.Intercepter接口就可以了。它定义了三个方法:

destory()//销毁该拦截器之前的回调方法

init()//初始化该拦截器的回调方法

String intercept(ActionInvocation invocation)throws Exception//拦截器实现拦截的逻辑方法

Struts2还提供了一个AbstractInterceptor类,该类提供了一个init和destory方法的空实现,如果我们实现的拦截器不需要申请资源,则可以直接继承此类。

下面实现一个简单的拦截器:

package com.test;

import com.annlee.login.action.LoginAction;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class TestStrutsIntercepter extends AbstractInterceptor {

//这里并未使用,演示而己,此参数可以在配置时指定
private String name;


public String getName() {
   return name;
}

public void setName(String name) {
   this.name = name;
}

@Override
public String intercept(ActionInvocation arg0) throws Exception {
   //取得被拦截的Action实例,这里并不进行操作,只是演示
   LoginAction action = (LoginAction)arg0.getAction();

   System.out.println("拦截器开始时间是:" + System.currentTimeMillis());
   String result = arg0.invoke();
   System.out.println("拦截器结束时间是:" + System.currentTimeMillis());
   return result;
}

}
配置拦截器,一是定义拦截器,如下:

<interceptors>
<interceptor name="pageParamInterceptor" class="test.TestStrutsIntercepter"></interceptor>
    <!-- 默认执行的拦截器栈 -->
    <interceptor-stack name="customStack">
     <!-- 引用STRUTS2默认拦截器 -->
     <interceptor-ref name="defaultStack"></interceptor-ref>
    </interceptor-stack>
   
   </interceptors>

注意这里的三个标签interceptors所有的拦截器和拦截器栈的定义都写在这里面,interceptor定义拦截器。

二是使用拦截器,前面已经做了介绍,只需要在Action中配置拦截器的关联即可。

 

4,开发只拦截某个方法的拦截器

在默认情况下,如果为某个Action定义了拦截器,则这个拦截器会拦截该Action内的所有方法,有时候我们只需要拦截某个Action中的特定方法,Struts2提供了一个MethodFilterInterceptor类,它是AbstractInterceptor类的子类,我们如果想过滤方法的话,应该继承MethodFilterInterceptor类。我们只要重写这个类的doIntercept(ActionInvocation invocation)方法就可以了,下面是一个简单的例子,代码如下:

package com.test;

import com.annlee.login.action.LoginAction;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

public class MyMethodInterceptor extends MethodFilterInterceptor{

//拦截器的名称,会在配置文件中注入
private String name;

public String getName() {
   return name;
}

public void setName(String name) {
   this.name = name;
}

/**
* 重写这个方法,可以实现对指定方法的拦截
*/
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
   //获取被拦截的Action实例
   LoginAction action = (LoginAction) invocation.getAction();
   System.out.println("拦截前的时刻:" + System.currentTimeMillis());
   String result = invocation.invoke();
   System.out.println("拦截后的时刻:" + System.currentTimeMillis());
   return result;
}

}
从上面的代码可以看出,上面的拦截器的拦截逻辑和前面的普通拦截器的拦截逻辑基本相同,只是普通拦截器是重写intercept方法,而这里是重写doIntercept方法。其它地方的代码都没有区别。

我们可以在配置是配置excludeMethod(不需要过滤的方法)和includeMethod(需要过滤的方法),如果一个方法在这两者都配置了,则includeMethod优先。配置文件如下:

   <interceptors>
    <interceptor name="myMethodFilter" class="com.test.MyMethodInterceptor">
     <param name="name">方法过滤拦截器</param>
    </interceptor>

   </interceptors>
  
   <action name="login" class="com.annlee.login.action.LoginAction" method="login">
    <result name="input">/login.jsp</result>
            <result name="success">/mainpage.jsp</result>
            <result name="failed">/common/error.jsp</result>
            <!-- 配置方法拦截器 -->
            <interceptor-ref name="defaultStack"></interceptor-ref>
            <interceptor-ref name="myMethodFilter">
            <param name="excludeMethods">execute,logout</param>
            <param name="includeMethods">login,valid</param>
            </interceptor-ref>

        </action>

Struts2提供了几个这类方法过滤拦截器:TokenInterceptor, TokenSessionInterceptor, DefaultWorkflowInterceptor, ValidationInterceptor

拦截器的执行过程是按照栈的后进先出原则来的。

5,拦截结果的拦截器

在前面开发的拦截器中,我们将在执行Action中方法的执行之前,执行之后的操作都定义在了拦截器的拦截方法中,我们同样可以精确定义在执行Action中方法的执行之后再执行拦截器的方法,这样可以实现对Action返回结果的监听。实现拦截结果的监听必须实现PreResultListener接口,下面的例子代码如下:

package com.test;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.PreResultListener;

public class MyPreResultListener implements PreResultListener {

/**
* 定义在返回结果之前的处理
*/
@Override
public void beforeResult(ActionInvocation invocation, String resultCode) {
   System.out.println("返回的视图逻辑是:" + resultCode);
}

}
这个监听器是通过代码手动注册给某个拦截器的,下面是应用的代码:

package com.test;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class BeforeResultInterceptor extends AbstractInterceptor {

@Override
public String intercept(ActionInvocation invocation) throws Exception {
   //注入一个拦截结果的监听给该拦截器
  invocation.addPreResultListener(new MyPreResultListener());
   String result = invocation.invoke();
   return result;  
}

}
这里要注意的一点就是在MyPreResultListener类中不能再次调用invocation.invoke()方法,这样程序会陷入一个死循环。

6,修改拦截器栈中特定拦截器的参数

有时候,我们在一个特定的Action中引用拦截器栈时,需要对拦截器栈中的某个拦截器的参数重新赋值,这里可以采用以下方法:

        <action name="login" class="com.annlee.login.action.LoginAction" method="login">
            <result name="input">/login.jsp</result>
            <result name="success">/mainpage.jsp</result>
            <result name="failed">/common/error.jsp</result>
            <!-- 这是一个包含多个拦截器的拦截器栈 -->
            <interceptor-ref name="my-stack">
            <!-- 将名为second的拦截器的name参数改掉 -->
            <param name="second.name">改名后的拦截器名</param>

            </interceptor-ref>
        </action>

7,Struts2的内建拦截器

从Struts2框架来看,拦截器几乎完成了Struts2框架70%的工作,包括解析请求参数,将请求参数赋值给Action属性,执行数据校验,文件上传。

Struts2已经自动为每个Action配置了默认拦截器,因此我们在大部分的情况下都不用再配置任何拦截器,它的配置如下:

<!-- 引用STRUTS2默认拦截器 -->
     <interceptor-ref name="defaultStack"></interceptor-ref>

8,实现权限控制拦截器

拦截器代码如下:

package com.test;

import java.util.Map;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class AuthorityInterceptor extends AbstractInterceptor {

@Override
public String intercept(ActionInvocation invocation) throws Exception {
   //获取请求相关的ActionContext实例
   ActionContext ctx = invocation.getInvocationContext();
   Map session = (Map) ctx.getSession();

   String user = (String) session.get("user");
   if(null==user){
    ctx.put("tips", "你还没有登录!");
    return Action.LOGIN;
   }else{
    return invocation.invoke();
   }
}

}

配置文件中的代码如下:

   <interceptors>
    <!-- 默认执行的拦截器栈 -->
    <interceptor-stack name="customStack">
     <!-- 引用STRUTS2默认拦截器 -->
     <interceptor-ref name="defaultStack"></interceptor-ref>

<interceptor name="pageParamInterceptor" class="com.miracle.dm.common.web.interceptor.PageParamInterceptor"></interceptor>
    </interceptor-stack>
   </interceptors>
  
<default-interceptor-ref name="customStack"></default-interceptor-ref>

分享到:
评论

相关推荐

    Struts2拦截器(Interceptor)

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

    Struts2拦截器及其用法详细说明

    在Struts2中,拦截器(Interceptors)扮演着核心角色,增强了框架的功能和灵活性。这篇文章将深入探讨Struts2拦截器的概念、工作原理以及如何在实际应用中使用它们。 **一、什么是Struts2拦截器** 拦截器是基于AOP...

    struts2 拦截器

    2. **拦截器链**:在Struts2中,多个拦截器可以形成一个拦截器链,每个拦截器按照定义的顺序依次执行。如果所有拦截器都允许Action执行,那么Action的结果将被传递到下一个拦截器,直到整个链执行完毕。 ### 二、...

    struts2 拦截器实例

    在Struts2中,拦截器(Interceptor)扮演着核心角色,它们允许开发者在Action执行前后插入自定义的逻辑,如日志、权限检查、事务管理等。现在我们将深入探讨Struts2的拦截器机制及其实例应用。 ### 一、Struts2拦截...

    详解Struts2拦截器

    ### Struts2拦截器详解 #### 一、Struts2拦截器概述 Struts2框架作为Java Web开发中的一种流行框架,其核心组件之一便是**拦截器**。拦截器不仅在Struts2中扮演着重要角色,更是整个框架灵活性与扩展性的基石。...

    struts2拦截器

    标题“struts2拦截器”指的是Struts2框架中的拦截器机制,这是一个关键的组件,可以让我们在不修改实际业务代码的情况下,实现对请求处理流程的扩展和定制。 描述中提到的“基于struts2的拦截器测试,实现了页面的...

    Struts2拦截器.ppt

    Struts2拦截器.ppt Struts2拦截器.ppt Struts2拦截器.ppt

    Struts2拦截器实现权限控制demo

    在这个“Struts2拦截器实现权限控制demo”中,我们将深入探讨如何利用拦截器来实现细粒度的用户权限管理。 首先,我们需要了解Struts2中的拦截器工作原理。拦截器是基于Java的动态代理模式实现的,它们按照配置的...

    Struts2 拦截器

    拦截器是Struts2框架的核心特性之一,它们扮演着处理请求、增强功能和实现业务逻辑的角色。在Struts2中,拦截器就像过滤器一样工作,通过链式调用在动作执行前后进行预处理和后处理。 首先,我们来理解一下拦截器的...

    struts2拦截器的使用方法

    ### Struts2拦截器的使用方法 #### 一、Struts2拦截器概述 Struts2框架中的拦截器(Interceptor)是一种重要的机制,用于在Action执行前后进行一系列处理,比如参数验证、数据预处理等。它能够帮助开发者更加灵活...

    struts2拦截器应用小例子

    当请求到达控制器时,Struts2会依次调用这个栈中的拦截器,每个拦截器都有机会处理请求,然后决定是否将请求传递给下一个拦截器或直接返回响应。 创建一个简单的Struts2拦截器,你需要遵循以下步骤: 1. 创建拦截...

    Struts2拦截器源程序

    在Struts2中,拦截器扮演着至关重要的角色,它们是实现MVC(Model-View-Controller)架构的关键组件之一。拦截器允许开发者在动作执行前后插入自定义逻辑,比如日志记录、权限检查、数据验证等,而无需修改核心业务...

    Struts2拦截器原理分析

    拦截器是Struts2框架的核心组成部分,它们在请求处理流程中起到了关键的作用。在本文中,我们将深入探讨Struts2拦截器的工作原理。 ### 一、拦截器概念 拦截器是基于Java的动态代理机制实现的,它允许我们在Action...

    struts2拦截器实现拦截不文明字迹

    拦截器是Struts2框架的一个重要组成部分,能够帮助开发者实现一些在请求处理前后执行的通用逻辑,如日志记录、权限验证、数据校验等。在本场景中,我们将探讨如何使用Struts2拦截器来实现对不文明字迹或者敏感词汇的...

    Struts2拦截器源码

    首先,理解拦截器的定义:拦截器是AOP(面向切面编程)的一个概念,在Struts2中,拦截器是基于Java的动态代理机制实现的。它们是一系列实现了`Interceptor`接口的类,可以在Action执行前后插入额外的行为。这些行为...

    使用struts2拦截器对登陆权限验证

    在Struts2中,拦截器(Interceptor)扮演着至关重要的角色,它允许开发者在动作执行前后插入自定义逻辑,如日志记录、权限验证等。在本案例中,我们将深入探讨如何使用Struts2拦截器实现登录权限验证,同时结合...

    Struts2学习案例(拦截器)

    在本学习案例中,重点在于Struts2的拦截器(Interceptor)功能,这是Struts2的核心特性之一,它允许开发者在Action执行前后进行自定义处理,实现了灵活的业务逻辑控制和增强的功能。 首先,我们来理解一下什么是...

    创建自己struts2拦截器

    Struts2是一个强大的MVC框架,它通过使用拦截器(Interceptor)来实现业务逻辑与表现层的解耦,提供了一种灵活的扩展机制。在Struts2中,拦截器是AOP(面向切面编程)的一种实现,它可以监控、修改或增强方法调用的...

    struts2拦截器实现权限控制

    这篇博客文章“struts2拦截器实现权限控制”深入探讨了如何利用Struts2的拦截机制来执行用户访问权限的验证。 在Struts2中,拦截器是基于AOP(面向切面编程)的概念设计的,它们在Action调用前后执行,可以添加额外...

    Struts2 拦截器注解(二十七)

    拦截器是Struts2框架的核心组件之一,它允许开发者在动作执行前后插入自定义逻辑,实现如权限验证、日志记录、性能优化等多种功能。在"Struts2 拦截器注解"这个主题中,我们将深入探讨如何利用注解来简化拦截器的...

Global site tag (gtag.js) - Google Analytics