一、拦截器

1、拦截器小介

拦截器的功能类似于web.xml文件中的Filter,能对用户的请求进行拦截,通过拦截用户的请求来实现对页面的控制。拦截器是在Struts-core-2.2.3.jar中进行配置的,原始的拦截器是在struts-default.xml中配置的,里面封存了拦截器的基本使用方法。

Struts2拦截器功能类似于Servlet过滤器。在Action执行execute方法前,Struts2会首先执行struts.xml中引用的拦截器,如果有多个拦截器则会按照上下顺序依次执行,在执行完所有的拦截器的interceptor方法后,会执行Action的execute方法。

Struts2的拦截器必须从com.opensymphoy.xwork2.interceptor.Interceptor中实现该接口,在被定义的拦截器中有下面三个方法需要被实现:

voiddestroy();

voidinit();

String intercept(ActionInvocation invocation) throwsException;

自定义的拦截器需要重写上面三个方法。另外Struts2的拦截器配置文件struts.xml它是继承了原始文件struts-default.xml文件的,这样在相应的中就会自动拥有struts-default.xml中的所有配置信息了。具体代码如下:

...

2、Demo

想要使用拦截器必须要经过配置,struts2采用的是映射的方法,所以想用使用某一个功能就必须在配置文件中配置,拦截器也不例外。所以必须在package中添加相应的拦截器元素,同时将拦截器关联相应的class文件,这样在执行action前才会执行相应的拦截器,具体使用方法如下。

(1)添加配置文件struts.xml,并在该文件中添加拦截器

/error.jsp

/success.jsp

/checkSession.jsp

上面的package中添加了一个名为myInterceptor的拦截器,并为该拦截器注册了一个java类,该类名称为MyInterceptor,并被封存在com.interceptor包中。另外还在该package中添加了相应的action,在执行该action前会首先执行myInterceptor拦截器。

(2)编写被注册的拦截器类MyInterceptor,该类必须实现com.opensymphoy.xwork2.interceptor.Interceptor接口,并重写相应的方法

packagecom.interceptor;

importjava.util.Map;

importcom.entity.User;

importcom.opensymphony.xwork2.ActionContext;

importcom.opensymphony.xwork2.ActionInvocation;

importcom.opensymphony.xwork2.interceptor.Interceptor;

publicclassMyInterceptorimplementsInterceptor{

privateUser user;

publicUser getUser() {

returnuser;

}

publicvoidsetUser(User user) {

this.user = user;

}

@Override

publicvoiddestroy() {

// TODO Auto-generated method stub

System.out.println("----destroy()----");

}

@Override

publicvoidinit() {

// TODO Auto-generated method stub

System.out.println("-----Init()-------");

}

@Override

publicString intercept(ActionInvocation invocation)throwsException {

// TODO Auto-generated method stub

System.out.println("----intercept()------");

Map session= invocation.getInvocationContext().getSession();

if(session.get("username")!=null){

System.out.println("登陆成功!");

//session.put("username",user.getUsername());

returninvocation.invoke();

}else{

System.out.println("登陆失败!");

return"checkError";

}

}

}

(3)经过前面两步后,拦截器已经配置完成,最后一部就是使用拦截器了,在显示页面上添加相应的标签,并为标签指定上面创建的名为demo的action,然后执行页面即可在控制台中打印出相应的拦截器内容。

pageEncoding="UTF-8"%>

html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

Insert title here

用户名:

密  码:

打印输出内容:

分析输出结果,程序编译阶段首先会去读取配置文件struts.xml,在该配置文件action中顺序查找是否添加了拦截器,如果添加了拦截器则根据拦截器名称在中查找是否定义了该拦截器或者拦截器栈,如果发现定义的是拦截器则根据拦截器查找对应的注册的class,最后在包内查找注册的class并执行相应的init()方法;程序运行阶段的大致流程和编译阶段类似,用户在前台提交请求后,会按照注册的action在struts.xml中查找与之相对应的,如果查找到将会查找拦截器,没有查找到的话会相应的抛错,最后执行拦截器注册类的intercept方法。

3、拦截器栈

拦截器同样有栈的概念,它是将使用的拦截器定义到共有的状态下来实现统一管理,这样在package中就可以做到拦截器的共享了,大大便利了拦截器的使用。在一个package中往往会用到重复的interceptor,如果每次都在Action中添加interceptor-ref的话就会很麻烦,那么拦截器栈就是为了解决这个问题而产生的,具体配置如下:

/error.jsp

/success.jsp

/checkSession.jsp

实例中使用了interceptor-stack来定义了一个名称为defaultstack1的拦截器栈,在该栈中添加了要执行的拦截器,把拦截器做了封装,在Action中直接调用该拦截器栈即可,实现了拦截器栈的共享。

4、默认拦截器栈

另外可以定义默认的拦截器栈,即:如果某个Action中没有定义拦截器,那么它会默认执行该公共的拦截器。它和interceptors标签属于同一等级的,使用default-interceptor-ref定义。

/error.jsp

/success.jsp

/checkSession.jsp

定义的默认的拦截器栈只是在Action没有指定拦截器的情况下才执行自定义默认的拦截器栈的,如果在Action中重定义了拦截器,那么它会覆盖自定义默认的拦截器栈的。

5、不执行任何拦截器

还有一种情况是一个package中定义了默认的拦截器,但是在编写的某个Action中并不需要执行任何拦截器,那么此时可以在相应的Action中添加一个名称为defaultStack的拦截器即可,它是系统默认的拦截器,不会有任何操作。

/error.jsp

/success.jsp

/checkSession.jsp

6、拦截方法

6.1 用法

上面的拦截器只是实现了对Action的拦截,其实拦截器的功能很强大,它也可以拦截相应Action方法。和拦截Action不同的是想要拦截方法就必须继承类MethodFilterInterceptor,该类封存在xwork-core.jar中,又一次证明了WebWork是Struts2的核心。另外还需要在配置文件中添加相应的属性来确定拦截的方法和不拦截的方法,具体配置方法如下:

/error.jsp

/success.jsp

/checkSession.jsp

添加要拦截的方法名称

添加不需要拦截的方法名称

继承MethodFilterInterceptor类的相应拦截方法的类中的代码:

packagecom.interceptor;

importjava.util.Map;

importcom.opensymphony.xwork2.ActionContext;

importcom.opensymphony.xwork2.ActionInvocation;

importcom.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

publicclassinterextendsMethodFilterInterceptor {

@Override

publicString doIntercept(ActionInvocation invocation)throwsException {

System.out.println("--intercept()--");

//获取相应的Session

Map session=invocation.getInvocationContext().getSession();

Map request=(Map)ActionContext.getContext().get("request");

String username=(String)request.get("user.username");

if(session.get("username") !=null){

String result=invocation.invoke();

System.out.println("--end()--");

returnresult;

}

}

}

6.2 Demo

来看一个拦截方法的实例,并对结果进行分析。下面的实例演示拦截方法的输出结果,在实例中分别创建了一个loginAction类,添加Action要执行的方法;Inter类,拦截器中重写MethodFilterInterceptor方法,在控制台中输出是否对某个方法进行拦截;login.jsp文件,添加三个按钮,分别演示三个方法的执行。

(1)struts.xml内方法拦截器的定义,在package中定义了一个名称为inter的拦截器,在拦截器中指定了参数,includeMethods用来拦截Method1,excludeMethods中的Method2表示不拦截Methods2方法,具体配置如下代码:

struts PUBLIC

"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

"http://struts.apache.org/dtds/struts-2.0.dtd">

Method1

Method2

success.jsp

error.jsp

Welcome

(2)loginAction类,配置login.jsp中的action,分别在该类中添加Method1-Method3三个方法,其中Method1被拦截,Method2和Method3不被拦截,最后我们查看输出结果。

packagecom.action;

importcom.opensymphony.xwork2.ActionSupport;

publicclassloginActionextendsActionSupport {

@Override

publicString execute()throwsException {

if(this.username.equals("admin") &&this.password.equals("admin")){

return"success";

}elseif(this.username.equals("cancel") &&this.password.equals("cancel")){

return"cancel";

}else{

return"error";

}

}

publicvoidMethod1(){

System.out.println("执行方法:Method1");

}

publicvoidMethod2(){

System.out.println("执行方法:Method2");

}

publicvoidMethod3(){

System.out.println("执行方法:Method3");

}

privateString username;

privateString password;

publicString getUsername(){

returnthis.username;

}

publicvoidsetUsername(String username){

this.username=username;

}

publicString getPassword(){

returnthis.password;

}

publicvoidsetPassword(String password){

this.password=password;

}

}

(3)inter类,继承MethodFilterInterceptor类,用来实现拦截方法。重写doIntercept方法,在该方法中添加拦截的相应信息。

packagecom.interceptor;

importjava.util.Date;

importjava.util.Map;

importcom.action.loginAction;

importcom.opensymphony.xwork2.ActionContext;

importcom.opensymphony.xwork2.ActionInvocation;

importcom.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

publicclassinterextendsMethodFilterInterceptor {

@Override

protectedString doIntercept(ActionInvocation invocation)throwsException {

// TODO Auto-generated method stub

System.out.println("拦截器在Action执行前拦截"+newDate());

String result=invocation.invoke();  //执行Action方法

System.out.println("拦截器在Action执行后拦截"+newDate());

returnresult;

}

}

(4)login.jsp,在jsp页面上添加三个按钮,分别演示三个方法,判断拦截器对方法的拦截情况。三个按钮在点击后回发的action是在javascript中动态的进行添加的,这样做达到了一个form中执行不同的action的方法,当然还有其它的方法,将会在下篇文章中讨论。

pageEncoding="UTF-8"%>

html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

Insert title here

//方法1,定义被拦截的方法的实例

function method1(){

var form=document.forms[0];

form.action="loginaction!Method1";

form.submit();

}

//方法2,为按钮2添加不拦截的方法

function method2(){

var form=document.forms[0];

form.action="loginaction!Method2";

form.submit();

}

//方法3,为按钮3添加不拦截的方法

function method3(){

var form=document.forms[0];

form.action="loginaction!Method3";

form.submit();

}

用户名:

密     码:

运行完成后的页面视图:

(5)分析运行结果,分别单击按钮1、2、3,在控制台中输出结果,按钮1是绑定的method1,该方法在struts.xml中进行了拦截如果结果正确的话会显示被拦截的结果,而相应的按钮2和3只输出运行结果,因为它们没有被拦截。那看下面的结果图:

结果图正好正是了我们的分析结果,按钮1被拦截了,执行了inter类中的doIntercept方法,二相应的按钮2和3没有被拦截。也就是说,Method1被放到了方法拦截器的白名单内,执行要拦截该方法;Method2被放到了拦截器黑名单内,不需要拦截该方法;Method3不做任何处理。

结语

对于拦截器的内容就总结到这里,拦截器提供了很强大的功能,使得开发人员能够在运行时控制输出结果,增加了编程的灵活性。另外对于任何理论性的东西都不要试图去记忆,一定要理性的去分析,多多实践,动手做几个实例,分析结果更深刻的理解。

java中拦截这个类的方法_类拦截器和方法拦截器相关推荐

  1. Java 中子类是否只继承父类的非私有变量和方法?

    今天在 CSDN 论坛中见到有人问在 Java 中子类是否只继承父类的非私有变量和方法(原贴在此).大部分跟贴都认为这句话是正确的,但是对于这个问题背后的本质理解却是错误的. 首先我们明确一下&quo ...

  2. Java中FTPClient上传中文目录、中文文件名乱码问题解决方法

    Java中FTPClient上传中文目录.中文文件名乱码问题解决方法 参考文章: (1)Java中FTPClient上传中文目录.中文文件名乱码问题解决方法 (2)https://www.cnblog ...

  3. java中demo接人_return的用法_如何理解java中return的用法?

    C语言中return用法?(请熟练者进) return是返回值,这个返回值是和函数的类型有关的,函数的类型是什么,他的返回值就是什么 比方主函数intmain() {}这里就必须有一个return,只 ...

  4. C++ 类与对象_类的其他成员(常成员,静态成员,友元)

    系列文章目录 重新复习c++,所以把书中的重点内容整理成博客,尽量简洁,易懂. C++ 类与对象_类和对象的定义与访问 (定义类和对象,访问对象成员,this指针) C++ 类与对象_构造函数和析构函 ...

  5. 在java中下列描述错误的是_在 JAVA 中 , 关于类的方法 , 下列描述错误的是 ()._学小易找答案...

    [多选题]价值的特性是 [简答题]输入任一字符串,统计其中数字,字母及其它字符个数 .(25分) [填空题]1.产品整体包括哪五个基本层次 2核心层次产品最基本的层次,是产品的_____ [单选题]纸 ...

  6. kotlin调用类中的方法_一种轻松的方法来测试Kotlin中令人沮丧的静态方法调用

    kotlin调用类中的方法 by Oleksii Fedorov 通过Oleksii Fedorov 一种轻松的方法来测试Kotlin中令人沮丧的静态方法调用 (A stress-free way t ...

  7. java中字符串和数组如何比较_[Java教程]javascript中数组和字符串的方法比较

    [Java教程]javascript中数组和字符串的方法比较 0 2016-07-19 23:00:05 ×目录[1]可索引 [2]转换 [3]拼接[4]创建[5]位置 前面的话 字符串和数组有很多的 ...

  8. java中的复合数据类型是什么_【填空题】类是Java中的一种重要的复合数据类型,是组成Java程序的基本要素。一个类的实现包括两部分:____和_____....

    [填空题]类是Java中的一种重要的复合数据类型,是组成Java程序的基本要素.一个类的实现包括两部分:____和_____. 更多相关问题 [名词解释] 观叶树木 [单选] 开花时有浓郁香气的树种是 ...

  9. dateformat 返回类型_详解Java中格式化日期的DateFormat与SimpleDateFormat类

    DateFormat其本身是一个抽象类,SimpleDateFormat 类是DateFormat类的子类,一般情况下来讲DateFormat类很少会直接使用,而都使用SimpleDateFormat ...

最新文章

  1. 炼成优秀 SaaS 产品的三个要素?听腾讯、神策、网易的专家讲讲|PCon
  2. Nvidia推出强大的新图形芯片Tesl V100加速进军AI和深度学习的步伐
  3. linux搜狗输入法配置,liunx----配置搜狗输入法
  4. 微软面试题目(一) 计算两个日期之间的天数
  5. py文件转exe时包含paramiko模块出错解决方法
  6. PHP的构成及生命周期
  7. MapReduce 作业调试
  8. c++调用python接口作用是_利用Boost::Python实现C++调用python接口
  9. 前端图片点击按钮加载更多内容_前端开发规范
  10. 使用图片拉伸resizableImageWithCapInsets
  11. Dgraph 1.2.8 发布,事务性分布式图形数据库
  12. 封校大学生无聊玩起图像大找茬——游戏脚本(一起领略Python脚本的风采吧)
  13. Spring Globle Transaction VS Local Transaction .
  14. 基于服务号的微信扫码关注公众号登录网站原理分析
  15. 如何利用任意波形发生器创建你想要的波形并输出
  16. win10 下安装wampserver 的几个坑
  17. 工厂模式-汽车工厂案例(附代码)
  18. ML-Agent——使用可执行.exe文件
  19. scratch和平使者 电子学会图形化编程scratch等级考试一级真题和答案解析2022年12月
  20. date月份加一_delphi 年月日自动加一减一函数,月加一,月减一

热门文章

  1. 利用POI读取excel文件(java)
  2. 最新完美UI好看币圈系统源码+无BUG/服务器直接打包
  3. math专栏 01.数学内容概述
  4. 3.18 钢笔工具的使用方法 [Illustrator CC教程]
  5. js关闭一个html页面跳转,js如何关闭当前页面
  6. 开发一个App到底成本多大?
  7. input 的value 含有英文双引号问题
  8. 【10】基于大数据hadoop框架实现PageRank算法
  9. MySQL第三次作业-----单表查询和多表查询
  10. 解决连接开放WIFI时,WIFI标志报感叹号的问题!