更新时间:2022-08-26 11:55
拦截器(Interceptor)是Struts2框架的核心功能之一,Struts 2是一个基于MVC设计模式的开源框架,主要完成请求参数的解析、将页面表单参数赋给值栈中相应属性、执行功能检验、程序异常调试等工作。Struts2拦截器是一种可插拔策略,实现了面向切面的组件开发,当需要扩展功能时,只需要提供对应拦截器,并将它配置在Struts2容器中即可,如果不需要该功能时,也只需要在配置文件取消该拦截器的设置,整个过程不需要用户添加额外的代码。拦截器中更为重要的概念即拦截器栈(Interceptor Stack),拦截器栈就是Struts2中的拦截器按一定的顺序组成的一个线性链,页面发出请求,访问Action对象或方法时,栈中被设置好的拦截器就会根据堆栈的原理顺序的被调用。
过滤器调度程序必须做的事情有很多,而没有驻留在过滤器调度程序类内部的代码往往会被模块化成一系列拦截器。拦截器可以通过编辑Struts配置文件而被插入或拔出。表格列出了Struts的默认拦截器。括号里部分是在配置文件里注册该拦截器时用的名字,在使用一个拦截器之前必须先在配置文件里注册它,例如,Alias拦截器的注册名是alias。
Struts 2中将各个功能对应的拦截器分开定义, 每个拦截器完成单个功能, 如果需要对Action运用某个功能就引用对应的拦截器。在实际开发中, 经常需要在Action执行前同时执行多个拦截动作, 如:用户登录检查、登录日志记录以及权限检查等, 这时, 可以把多个拦截器组成一个拦截器栈。所谓的拦截器栈是指对应各个功能的拦截器按照一定的顺序排列形成的链, 在使用时, 可以将栈内的多个拦截器当成一个整体来引用。当拦截器栈被附加到一个Action上时, 在执行Action之前必须先执行拦截器栈中的每一个拦截器。通常情况下, 拦截器都是以代理方式调用的。
Struts 2拦截器在Action执行前后进行拦截, 围绕着Action的执行而执行, 比如实现日志管理拦截器和安全功能的拦截器, 在系统的Action关联了拦截器, 添加到Action执行过程中以后, 系统的整个执行流程就变为:记录日志、执行安全检测、执行Action、执行安全检测、记录日志, 在执行的过程中, 每一个拦截器类的拦截方法决定是传递请求, 还是终止请求。
在实际的Web应用软件项目中, 与项目的业务逻辑相关的通用功能需要开发人员自定义拦截器实现。比如Web应用软件都要涉及到权限控制这部分, 当用户访问系统的受保护资源时, 需要先检查用户是否已经登录, 以及是否有权限访问, 可以由拦截器截获用户请求, 判断用户是否已经登录。
如果需要自定义拦截器类, 该类就需要实现Interceptor接口。这个接口提供了拦截器的生命周期方法: (1) init () 方法在拦截器被创建后调用, 对系统相关资源进行必要的初始化工作。 (2) destroy () 方法在拦截器对象被销毁之前调用, 用来释放和拦截器相关的资源。 (3) intercept (ActionInvocation invocation) 方法是拦截器的核心方法, 用来实现具体的拦截操作, 可以通过ActionInvocation参数的invoke () 方法, 将控制权转给下一个拦截器或者控制器Action。如果需要自定义拦截器类, 只需要实现Interceptor接口的三个方法即可。然而在实际开发过程中, 更常用的一种方式是继承抽象拦截器类AbstractIntercepter, 它实现了Interceptor接口, 因此可以直接继承该抽象类, 简化代码的编写。
判断用户是否登录, 可以跟踪用户的会话对象session来完成, 利用ActionContext对象就可以可访问到session中的属性, 拦截器执行拦截的intercepte方法的invocation参数可以得到ActionContext对象, 通过ActionInvocation参数取得用户的session实例的引用, 从而判断是否需要转入登录页面。
如果要使用权限控制拦截器, 还要在项目的配置文件struts.xml中定义该拦截器。由于Struts2中很多核心功能都是由系统默认的defaultStack中的拦截器实现的, 所以开发人员自定义的拦截器需要引用系统默认的defaultStack, 这样Web应用才可以使用Struts 2框架提供的众多功能。