第4章Struts2拦截器
本章学习目标
· 理解拦截器的意义
· 熟练掌握Struts2拦截器的使用
· 掌握自定义拦截器的使用
拦截器是Struts2框架的一个核心组件,也是Struts2的一大特色,很多功能都是构建在内置拦截器的,如数据校验、国际化等。Struts2利用其内建的拦截器可以完成大部分操作,当内置拦截器不能满足时,开发者也可以自己扩展自定义拦截器。
使用Struts2拦截器只需在配置文件配置即可,取消拦截器只需取消其配置,这是一种插拔式的设计,具有非常好的可扩展性,掌握并熟练运用拦截器,会大大提高开发效率,本章将详细讲解拦截器的相关知识。
4.1拦截器的概述和意义
在JavaWeb阶段学过Filter过滤器,多个Filter构成过滤器链。Filter与拦截器很像,二者都是AOP编程思想的体现,都能实现权限检查、日志记录等,但他们也稍有不同,Filter只能用于Web程序中,是Servlet规范中定义的,另外它们处理的粒度也是不同的,Filter只在Servlet前后起作用,而拦截器能深入方法前后、异常抛出前后等,因此拦截器有更强大的功能,本节将介绍拦截器的概念和意义。
4.1.1拦截器概述
拦截器是在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作,拦截器就是AOP的一种实现策略。
Webwork的中文文档的解释为拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式。
谈到拦截器,还有一个词读者应该知道——拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
拦截器的调用是分开的,各个拦截器负责自己的功能,不去管其他的拦截器,这种模块的设计更好地体现了MVC的组件化设计思想。另外,拦截器与Action存在着紧密的关系,如图4.1所示。
图4.1 拦截器与Action关系图
如上图所示,用户操作浏览器向Web应用发送HttpServletRequest请求,请求经过各种过滤器的过滤并传递给核心控制器,核心控制器会调用Action映射器ActionMapper,将用户情趣转发到对应的业务逻辑控制器,此业务逻辑控制器并不是用户实现的业务控制器,而是Struts2创建的Action代理ActionProxy,用户实现的Action类仅仅是Struts2的ActionProxy的代理目标,ActionProxy通过Configuration Manager在struts.xml的配置文件中搜索被请求的Action类,ActionProxy创建一个被请求Action的实例,用来处理客户端的请求信息,如果在struts.xml配置文件存在与被请求Action相关的拦截器配置,那么该Action实例被调用的前后,这些拦截器将会被执行,Action对请求处理完毕后会返回一个逻辑视图,由此逻辑视图找对相应物理视图返回给客户端。
4.1.2拦截器的意义
拦截器是对调用方法的改进,实际上,拦截器也是一个类,类中包含方法,只不过这个方法是特殊的方法,它会在目标方法调用之前自动执行。
如果不使用拦截器,代码中需要显式通过代码来调动目标方法,这样会造成多个程序间的冗余,这种做法明显是不合理的,违背了软件开发的基本原则,不便于后期维护和扩展。
由上可见,拦截器是解决重复性问题的重要方式,它提供了更高层次的解耦和抽象,目标代码无须手动调用目标方法,由程序自动完成,这种调用从代码层面上升到了设计层面。
4.2Struts2拦截器
学习了拦截器的概念和意义后,接下来详细讲解如何配置和使用拦截器。
4.2.1配置并使用Struts2拦截器
在struts-default.xml文件中定义了很多拦截器,如果要使用其中的拦截器,只需要在struts.xml文件中通过""将struts-default.xml文件包含进来,并继承其中的struts-default包(package),最后在定义Action时,使用""引用拦截器或拦截器栈(interceptor stack)。接下来通过一个案例演示如何配置并使用拦截器,新建动态Web工程,在web.xml中配置Struts2核心控制器,这里就不再重复演示,然后编写后台代码,如例4-1所示。
1 TimerInterceptorAction.java
2 import com.opensymphony.xwork2.ActionSupport;
3 public class TimerInterceptorAction extends ActionSupport {
4 private static final long serialVersionUID = 1L;
5 @Override
6 public String execute() {
7 try {
8 // 模拟耗时的操作
9 Thread.sleep(500);
10 } catch (Exception e) {
11 e.printStackTrace();
12 }
13 return SUCCESS;
14 }
15 }
接着编写struts.xml配置文件,如例4-2所示。
例4-1 struts.xml
1
2
3 "-//Apache Software Foundation//DTD Struts
4 Configuration 2.5//EN"
5 "http://struts.apache.org/dtds/struts-2.5.dtd"
特别声明:文章来源用户上传并发布,本站只提供信息存储服务,不拥有所有权,内容仅供参考。