Struts2教程9:实现自已的拦截器

   在上一篇中介绍了Struts2拦截器的原理,在这一篇中我们将学习一下如何编写自己的拦截器。
一、拦截器的实现
     实现一个拦截器非常简单。实际上,一个拦截器就是一个普通的类,只是这个类必须实现com.opensymphony.xwork2.interceptor.Interceptor接口。Interceptor接口有如下三个方法:


public interface Interceptor extends Serializable 
{
    
void destroy();
    
void init();
    String intercept(ActionInvocation invocation) 
throws Exception;
}

其中initdestroy方法只在拦截器加载和释放(都由Struts2自身处理)时执行一次。而intercept方法在每次访问动作时都会被调用。Struts2在调用拦截器时,每个拦截器类只有一个对象实例,而所有引用这个拦截器的动作都共享这一个拦截器类的对象实例,因此,在实现Interceptor接口的类中如果使用类变量,要注意同步问题。
下面我们来实现一个简单的拦截器,这个拦截器通过请求参数action指定一个拦截器类中的方法,并调用这个方法(我们可以使用这个拦截器对某一特定的动作进行预处理)。如果方法不存在,或是action参数不存在,则继续执行下面的代码。如下面的URL
http://localhost:8080/struts2/test/interceptor.action?action=test
访问上面的url后,拦截器会就会调用拦截器中的test方法,如果这个方法不存在,则调用invocation.invoke方法,invoke方法和Servlet过滤器中调用FilterChain.doFilter方法类似,如果在当前拦截器后面还有其他的拦截器,则invoke方法就是调用后面拦截器的intercept方法,否则,invoke会调用Action类的execute方法(或其他的执行方法)。
下面我们先来实现一个拦截器的父类ActionInterceptor。这个类主要实现了根据action参数值来调用方法的功能,代码如下:


package interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
import javax.servlet.http.*;
import org.apache.struts2.*;

public class ActionInterceptor implements Interceptor
{
    
protected final String INVOKE = "##invoke";
   
    
public void destroy()
    {
        System.out.println(
"destroy");
    }

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

    
public String intercept(ActionInvocation invocation) throws Exception
    {    
        HttpServletRequest request 
= ServletActionContext.getRequest();
        String action 
= request.getParameter("action");
        System.out.println(
this.hashCode());
        
if (action != null)
        {
            
try
            {
                java.lang.reflect.Method method 
= this.getClass().getMethod(action);
                String result 
= (String)method.invoke(this);
                
if(result != null)
                {
                    
if(!result.equals(INVOKE))
                        
return result;
                }
                
else
                    
return null;
            }
            
catch (Exception e)
            {
            }
        }
        
return invocation.invoke();
    }
}

从上面代码中的intercept方法可以看出,在调用action所指定的方法后,来判断返回值。可能发生的情况有三种:
1.        返回值为null,执行return null
2.        返回值为INVOKE,执行return invockation.invoke()
3.        其他情况,执行return result result表示指定方法的返回值,如上面代码所示。
    在实现完上面的拦截器父类后,任何继承于ActionInterceptor类的拦截器都可以自动根据action的参数值调用自身的相应方法。下面我们来实现一个拥有两个动作方法testprint的拦截器类。代码如下:


package interceptor;

import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;

public class MultiMethodInterceptor extends ActionInterceptor
{
    
public String test() throws Exception
    {
        HttpServletResponse response 
= ServletActionContext.getResponse();
        response.getWriter().println(
"invoke test");
        
return this.INVOKE;
    }

    
public String print() throws Exception
    {
        HttpServletResponse response 
= ServletActionContext.getResponse();
        response.getWriter().println(
"invoke print");

        
return null;
    }
}

test方法返回了INVOKE,因此,在执行完这个方法后,Struts2会接着调用其他拦截器的intercept方法或Action类的execute方法。而print方法在执行完后,只是返回了null,而不再调用其他的方法了,也就是访问如下的url时,动作的execute方法将不会执行:

    http://localhost:8080/struts2/test/ddd.action?action=print
    下面我们来实现一个Action类,代码如下:

package action;

import org.apache.struts2.*;
import com.opensymphony.xwork2.ActionSupport;

public class InterceptorAction extends ActionSupport
{
    
public String abcd() throws Exception
    {
        ServletActionContext.getResponse().getWriter()
                .println(
"invoke abcd");
        
return null;
    }
}

在这个Action类中,只有一个abcd方法,实际上,这个方法相当于execute方法,在下面会设置动作的method属性为abcd。下面我们来在struts.xml中定义拦截器类和动作,代码如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd"
>
<struts>
    
<package name="demo" extends="struts-default" namespace="/test">
        
<interceptors>
            
<interceptor name="method" class="interceptor.MultiMethodInterceptor" />
                
<interceptor-stack name="methodStack">
                    
<interceptor-ref name="method" />
                    
<interceptor-ref name="defaultStack" />
                
</interceptor-stack>
        
</interceptors>

        
<action name="interceptor" class="action.InterceptorAction" method="abcd">
            
<interceptor-ref name="methodStack" />
        
</action>
    
</package>
</struts>

在配置上面的methodStack拦截器时要注意,最好在后面引用defaultStack,否则很多通过拦截器提供的功能将失去。
OK,现在访问如下的URL

    http://localhost:8080/struts2/test/ddd.action?action=test
在浏览器中将会出现如下的字符串:

    invoke test
invoke abcd
而如果访问http://localhost:8080/struts2/test/ddd.action?action=print,将会只出现如下的字符串:

    invoke print
大家可以看出,访问这个url时并没有调用abcd方法。如果随便指定的action值的话,则只调用abcd方法,如访问http://localhost:8080/struts2/test/ddd.action?action=aaa,就只会输出invoke abcd

二、拦截器的参数

    
我们在使用很多Struts2内置的拦截器时会发现有很多拦截器都带参数,当然。我们自己做的拦截器也可以加上同样的参数。有两个参数比较常用,这两个参数是includeMethodsexcludeMethods,其中includeMethods指定了拦截器要调用的Action类的执行方法(默认是execute),也就是说,只有在includeMethods中指定的方法才会被Struts2调用,而excludeMethods恰恰相反,在这个参数中指定的执行方法不会被Struts2调用。如果有多个方法,中间用逗号(,)分隔。在Struts2中提供了一个抽象类来处理这两个参数。这个类如下:

com.opensymphony.xwork2.interceptor.MethodFilterInterceptor

    
如有继承于这个类的拦截器类都会自动处理includeMethodsexcludeMethods参数,如下面的拦截器类所示:

package interceptor;

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

public class MyFilterInterceptor 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
    {
        System.out.println(
"doIntercept");
        System.out.println(name);
        
return invocation.invoke();
    }
}

    MethodFilterInterceptor的子类需要实现doIntercept方法(相当于Interceptorintercept方法),如上面代码所示。在上面的代码中还有一个name属性,是为了读取拦截器的name属性而设置的,如下面的配置代码所示:


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd"
>
<struts>
    
<package name="demo" extends="struts-default" namespace="/test">
        
<interceptors>
            
<interceptor name="method" class="interceptor.MultiMethodInterceptor" />
                
<interceptor name="filter"
                    class
="interceptor.MyFilterInterceptor">
                    
<param name="includeMethods">abcd</param>
                    
<param name="name">中国</param>
                
</interceptor>
                
<interceptor-stack name="methodStack">
                    
<interceptor-ref name="method" />
                    
<interceptor-ref name="filter" />
                    
<interceptor-ref name="defaultStack" />
                
</interceptor-stack>
        
</interceptors>

        
<action name="interceptor" class="action.InterceptorAction" method="abcd">
            
<interceptor-ref name="methodStack" />
        
</action>
    
</package>
</struts>

    再次访问http://localhost:8080/struts2/test/ddd.action?action=test, Struts2就会调用MyFilterInterceptordoIntercept方法来输出name属性值。如果将上面的includeMethods参数值中的abcd去掉,则Action类的abcd方法不会被执行。





本文转自 androidguy 51CTO博客,原文链接:http://blog.51cto.com/androidguy/216451,如需转载请自行联系原作者

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/454098.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

标准C程序设计七---66

Linux应用 编程深入 语言编程标准C程序设计七---经典C11程序设计 以下内容为阅读&#xff1a; 《标准C程序设计》&#xff08;第7版&#xff09; 作者&#xff1a;E. Balagurusamy&#xff08;印&#xff09;&#xff0c; 李周芳译 清华大学出版社…

深度学习之概述

深度学习的应用场景 1、图像应用&#xff1a; 1.1 大规模(大数据量)图片识别(聚类/分类)&#xff0c;如人脸识别&#xff0c;车牌识别&#xff0c;OCR等。人脸识别算法&#xff1a;① faceID ② faceNet 1.2 以图搜图&#xff0c;图像分割 1.3 目标检测&#xff0…

如何根据对象获取到对应的表名_Excel VBA 常用对象二

下面继续讲解上一节中未讲完的内容&#xff1a;Excel VBA编程中常常使用的那些对象到底是什么&#xff0c;如何在代码中表示它们。Worksheet对象Worksheet对象代表工作表。工作簿中的每个工作表都是一个Worksheet对象&#xff0c;所有Worksheet对象构成了Worksheets集合。我们使…

PIX525故障一例,求解

IDC机房网络拓朴如下&#xff1a;IDC核心交换机-----通过一条网线-------机柜D-LNKI交换机------PIX 525------CISCO交换机------各WEB服务器。其中D-LINK交换机的IP为192.168.2.11&#xff0c;也就是下面日志中的IP。另外&#xff0c;之所以IDC和PIX之间再加一台DLINK是因为有…

gcc教程(转)

gcc 目 录 gcc makefile写法 gcc_egcs使用 gdb使用 gcc常用选项对代码的影响 一般情况 -O 编译选项 -O2 编译选项 -fomit-frame-pointer 编译选项 -fomit-frame-pointer && -O2 -fPIC 编译选项 -static 编译选项 AT&T的汇编格式 x86内联汇编 简述 内联汇编 程序模…

深度学习之 BP 算法

神经网络的一种求解W的算法&#xff0c;分为信号“正向传播(FP)”求损失&#xff0c;“反向传播(BP)”回传误差&#xff1b;根据误差值修改每层的权重&#xff0c;继续迭代。 BP算法也叫做δ算法。以三层的感知器为例&#xff08;假定现在隐层和输出层均存在相同类型的激活函数…

python自带的解释器叫做_python学习

一、PYTHON中的元素1.基本元素运算符&#xff1a; - * / %等等除法&#xff1a;" / " 表示浮点数除法&#xff0c;返回浮点结果;" // " 表示整数除法,返回不大于结果的一个最大的整数运算顺序&#xff1a;先乘除 再加减 括号最优先变量&#xff1a;就是一…

IE打印空白

今天碰到HR经理碰到一个问题&#xff0c;就是windows 7 64位操作系统&#xff0c;但是打印空白&#xff0c;打印出来像白纸一样&#xff01;经过查看和总结&#xff0c;确认是&#xff1a;由于保护模式下 %Temp%\Low 文件夹工作不正常引起的&#xff01;故障打印白纸下面会出现…

Python Matplotlib.plot Update image Questions

1. 最近在测试一款设备&#xff0c;采集了一些设备后需要一帧一帧显示图像&#xff0c;经常使用Python,所以选用了Matplotlib进行图像操作 数据结构&#xff1a; timesatamp polar_distance horizontal_angle refelectivity_intensity,所有数据类型都是 float&#xff0c;储存在…

深度学习之 RBF神经网络

RBF神经网络通常只有三层&#xff0c;即输入层、中间层和输出层。其中中间层主要计算输入x和样本矢量c&#xff08;记忆样本&#xff09;之间的欧式距离的Radial Basis Function (RBF)的值&#xff0c;输出层对其做一个线性的组合。 径向基函数&#xff1a; RBF神经网络的训练…

redis 队列_Redis与Rabbitmq消息队列的区别

将redis发布订阅模式用做消息队列和rabbitmq的区别&#xff1a;可靠性 redis &#xff1a;没有相应的机制保证消息的可靠消费&#xff0c;如果发布者发布一条消息&#xff0c;而没有对应的订阅者的话&#xff0c;这条消息将丢失&#xff0c;不会存在内存中&#xff1b;rabbit…

EasyUI中那些不容易被发现的坑——EasyUI重复请求2次的问题

问题控件&#xff1a;datagrid、combobox、所有能设置url属性的控件 问题版本&#xff1a;1.4.4、1.4.5&#xff08;之前的版本没测&#xff09; 问题如图&#xff1a; 重复请求2次&#xff0c;错误代码如图&#xff1a; 错误问题分析&#xff1a;html加载的时候回请求url加载数…

GCC编译的背后( 预处理和编译 汇编和链接 )

发表于 2010年05月18日 22:01 分类: 编程coding统计: 1评/465阅 2人收藏此文章&#xff0c; 收藏此文章(?)by falcon<zhangjinwgmail.com> 2008-02-22 平时在Linux下写代码&#xff0c;直接用"gcc -o out in.c"就把代码编译好了&#xff0c;但是这后面到底做了…

ElasticSearch Java API

ElasticSearch-Java Client类型 ElasticSearch-TransportClient环境准备 ElasticSearch-TransportClient连接 ElasticSearch-Document APIs ElasticSearch-搜索-原理 ElasticSearch-搜索-问题 ElasticSearch-搜索-问题解决思路 ElasticSearch-搜索-SearchType-类型一 E…

深度学习之卷积神经网络(Convolutional Neural Networks, CNN)

前面, 介绍了DNN及其参数求解的方法(深度学习之 BP 算法),我们知道DNN仍然存在很多的问题&#xff0c;其中最主要的就是BP求解可能造成的梯度消失和梯度爆炸.那么,人们又是怎么解决这个问题的呢?本节的卷积神经网络(Convolutional Neural Networks, CNN)就是一种解决方法. 我们…

Oracle DBA课程系列笔记(16)

第十六章&#xff1a; 用户管理 1、schema &#xff1a; user.object &#xff0c;用户认证方式&#xff1a;os 认证&#xff0c;database 认证 2、建立 database认证的用户&#xff1a; 10:00:48 SQL> create user rose …

python序列是几维_从一个1维的位数组获得一个特定的2维的1序列数组[Python] - python...

我正在使用Python&#xff0c;我需要找到执行以下任务的最有效方法。任务&#xff1a;给定零和一的任何一维数组v&#xff0c;用k> 0表示v的所有一维的子序列数。我需要从v获得一个二维数组w&#xff0c;使得&#xff1a;1)shape(w)(k&#xff0c;len(v))&#xff0c;2)对于…

深度学习之卷积神经网络(Convolutional Neural Networks, CNN)(二)

前面我们说了CNN的一般层次结构, 每个层的作用及其参数的优缺点等内容.深度学习之卷积神经网络(Convolutional Neural Networks, CNN)_fenglepeng的博客-CSDN博客 一 CNN参数初始化及参数学习方法 和机器学习很多算法一样, CNN在进行训练之前也要进行参数的初始化操作. 我们…

GCC Inline ASM GCC内联汇编

GCC 支持在C/C代码中嵌入汇编代码&#xff0c;这些汇编代码被称作GCC Inline ASM——GCC内联汇编。这是一个非常有用的功能&#xff0c;有利于我们将一些C/C语法无法表达的指令直接潜入C/C代码中&#xff0c;另外也允许我们直接写 C/C代码中使用汇编编写简洁高效的代码。1.基本…

Hadoop1.x版本升级Hadoop2.x

引言 随着企业数据化和Hadoop的应用越加广泛&#xff0c;hadoop1.x的框架设计越来越无法满足人们对需求&#xff0c;Apache一直在对Hadoop1.x进行修改&#xff0c;最后推出了新一代的Hadoop2.x。从业界使用分布式系统的变化趋势和 hadoop 框架的长远发展来看&#xff0c;MapRed…