struts2学习笔记 ⑤
拦截器初探
昨天临睡觉之前看了看拦截器,也在昨天的学习笔记里面胡诌诌了几句,今天就来好好的会会拦截器这个东西。实际上拦截器是一种模块实现的机制<起码我是这么体会的>(至于说书里面说体现了AOP的设计思想…我连AOP是啥还没搞清楚好伐…),在struts1的版本里面,struts将所有的功能围绕着核心控制器来实现的,而到了Struts2,控制器不在承担过多的功能支持,将这些功能拓展交给拦截器来完成。
拦截器设计为在action之前或action之后执行,从系统的架构图也能看出来,除了系统核心的拦截器外,你还可以插入其他的拦截器。
拦截器还有一个好处,就是解耦合。比如说A方法中需要验证username长度不能超过25位,B方法也需要,C方法也需要,那么我们就可以考虑将这个验证放在一个拦截器中实现,在执行Action之前执行,如果错误就返回,如果正确继续执行Action。
那么到底拦截器的原理是什么呢?我觉得从struts的书上是找不到答案了,度娘帮一下,下面是度娘给的定义…
java里的拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提取action中可重用部分的方式。在AOP(Aspect-Oriented Programming)中拦截器用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。
这么一查的倒是提醒我了,有一点很重要,拦截器并非什么特殊的代码,他只是一个Java类,实现起来很简单。还有就是拦截器与过滤器的区别:
过滤器可以简单理解为
取你所想取
忽视掉那些你不想要的东西;拦截器可以简单理解为
拒你所想拒
关心你想要拒绝掉哪些东西,比如一个BBS论坛上拦截掉敏感词汇。
1.拦截器是基于java反射机制的,而过滤器是基于函数回调的。
2.过滤器依赖于servlet容器,而拦截器不依赖于servlet容器。
3.拦截器只对action起作用,而过滤器几乎可以对所有请求起作用。
4.拦截器可以访问action上下文、值栈里的对象,而过滤器不能。
5.在action的生命周期里,拦截器可以多起调用,而过滤器只能在容器初始化时调用一次。
现在发现和自己的想法差不多,核心一句话“拒你所相拒”!
声明和使用拦截器
搞清楚概念和用途后,就该尝试一下了。我一直很讨厌书大而全,啥都给你讲,生怕你不知道乾隆的第42个娘娘的外婆的外甥女的爸爸叫啥,有必要么?我们需要将最常用的东西,其他就直接说有几种方法,其中哪两种已经不适用了,我们介绍这种,就OK了,唉….
现在开发实际上都是直接在struts.xml配置拦截器,这样就避免了在类中指定的高耦合的情况。在Struts.xml配置过滤器的格式是:
<interceptor name=”interceptorName”class=”interceptorClass /></interceptor>
实际上定义的格式与Action十分类似。如果你像向配置的拦截器传递参数你还可以在标签之中添加param标签,指定你需要传递的参数即可。
在开发中往往需要多个拦截器配合使用,这时候需要一个拦截器栈了。他的定义就是
<interceptor-stack name=”xxx”></interceptor-stack>在标签里面使用
<interceptor-ref>标签来指定拦截器。
具体怎么使用通过例子来演示吧,没有例子干看配置,总也不会太明白的,也没兴趣。
当然还有几个概念:
默认拦截器
<default-interceptor-ref name=”已经存在的拦截器或拦截器栈的名字”/>这个标签是package的子标签。
内建拦截器
我们没有配置拦截器的时候,你就已经可以获取到HHTP请求的传值了,这就是因为内建拦截器把参数拿到了存到了你可以拿到的地方。
内建拦截器就像一个工具库一样,为你提供了很多使用的东西,比如说提供文件上传功能的fileUpload啊,比如说输出Action执行时间的Timer等等等,这些内建拦截器用到了去查就行了。
下面看一看怎样自定义一个拦截器来扩展struts的功能:
首先需要实现Interceptor接口,需要实现三个方法,init、destory和interceptor。那么Struts2的AbstractInterceptor已经为我们实现了Interceptor接口,大多数情况下我们直接继承AbstractInterceptor就可以了,这个和Action接口与ActionSupport类的关系很相似。
下面是一个拦截器的实现:
package tech.youngs.Interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;public class RegInterceptor extends AbstractInterceptor{
private static final long serialVersionUID = 1L;@Override
public String intercept(ActionInvocation arg0) throws Exception {
// TODO Auto-generated method stub
System.out.println("拦截器开始工作");
String result = arg0.invoke();
System.out.println("拦截器结束工作");
return result;
}}
Action的代码其实没什么特别的就不贴了,这里贴出struts.xml的配置代码:
<interceptors>
<interceptor name="register" class="tech.youngs.Interceptor.RegInterceptor"/>
</interceptors>
<action name="reg" class="tech.youngs.Action.RegisterAction">
<result name="success">/WEB-INF/jsp/success.jsp</result>
<result name="input">/WEB-INF/jsp/reg.jsp</result>
<interceptor-ref name="defaultStack" />
<interceptor-ref name="register" />
</action>
特别注意 是<interceptors>标签里面定义着拦截器 在action里面使用<interceptor-ref>引用就行了。在写代码的时候还出现了一个错误,就是引用的定义的拦截器的name不相同了,给我报404的页面,现在体会着struts报了404绝壁是配置文件除了问题,慢慢找就行了 注意一下什么name想不想同啊 这一类的问题。
拦截器深入
上面只介绍了拦截器的原理,还不知道内部是怎么运行的,输出了一下args.invoke 控制台显示了input也就是不成功的时候的字符串。这个东西我觉得网上的文章说的很好:
invocation.invoke() 就是通知struts2接着干下面的事情
比如 调用下一个拦截器 或 执行下一个Action
就等于退出了你自己编写的这个interceptor了
1. 如果拦截器堆栈中还有其他的Interceptor,那么invocation.invoke()将调用堆栈中下一个Interceptor的执行。
2. 如果拦截器堆栈中只有Action了,那么invocation.invoke()将调用Action执行。
特别注意,在使用自定义拦截器的时候,必须引用struts2自带的拦截器缺省堆栈defaultStack,不然会出错。
在实际的开发过程中,实际很少会对整个Action去拦截,可能只需要对某几个方法去进行验证之类的工作,那么struts提供了一种过滤方法的拦截器,这个拦截器与普通拦截器的唯一不同就是,继承了MethodFilterIntercepter,这个类已经继承了AbstractInterceptor,它重写了intercept方法,还提供了doIntercept的抽象方法供用户实现。
其实MethodFilterIntercepter与普通的拦截器的实现代码没什么区别。那么怎么实现过滤到需要拦截的方法呢——struts.xml继续看….
<intercepter-ref name=”xxxInterceptor”>
<param name=”executeMethods”>execute,login</param>
</intercepter-ref>
在引用自定义拦截器的时候,增加一个名为executeMethods的参数就行了,中间的方法名将不会被拦截,特别注意是executeMethods,这个在声明拦截器的时候的坑很像,就是复数,而且这种错误犯了的话会很难找的,interceptors和executeMethods。中间的方法名使用都好隔开就行了。
下面看一个比较高级的例子吧,权限控制。这个我在PHP的时候做过,思路就是库内的用户权限有单独的字段,然后他登录了权限字段会存入Session中,那么页面会判断你这个session里的权限是不是满足访问页面的最低权限,ok就进,or就出,就是这样的思路。
这里记一下ActionContext的几种获取方式:
- 在自定义的拦截器中:使用ActionInvocation.getInvocationContext()或者使用ActionContext.getContext()。
- 在Action类中:让拦截器注入或者使用ActionContext.getContext()。
- 在非Action类中:让Action类传递参数、使用注入机制注入或者使用ActionContext.getContext()。注意:只有运行在request线程中的代码才能调用ActionContext.getContext(),否则返回的是null。
在上面我们看到,在自定义的拦截器中两种方式实际上是对等的。
在MVC框架里面有这样一条开发的原则,尽量不要再Controller层做过多的判断,这真的是一条比较好的法则,希望各位小伙伴们在开发的时候遵循。
那么在Struts2内也是一样的,我们不要讲权限的判断交给Action去执行,我们将权限的控制放在拦截器中去实现:
…..我都郁闷了 弄了一下午sessionMap没有值…..
求大神解答 为啥ActionContext在interceptor里面没有值呢?
struts2学习笔记 ⑤的更多相关文章
- Struts2学习笔记⑧
今天是Struts2学习笔记的最后一篇文章了.用什么做结尾呢,这两天其实还学了很多东西,没有记录下,今天就查漏补缺一下. 文件上传与下载.FreeMarker以及昨天没做完的例子 文件上传与下载 文件 ...
- Struts2学习笔记①
Struts2 学习笔记① 所有的程序学习都从Hello World开始,今天先跟着书做一个HW的示例. Struts2是一套MVC框架,使用起来非常方便,接触到现在觉得最麻烦的地方是配置文件.我的一 ...
- Struts2学习笔记NO.1------结合Hibernate完成查询商品类别简单案例(工具IDEA)
Struts2学习笔记一结合Hibernate完成查询商品类别简单案例(工具IDEA) 1.jar包准备 Hibernate+Struts2 jar包 struts的jar比较多,可以从Struts官 ...
- Struts2 学习笔记(概述)
Struts2 学习笔记 2015年3月7日11:02:55 MVC思想 Strust2的MVC对应关系如下: 在MVC三个模块当中,struts2对应关系如下: Model: 负责封装应用的状态,并 ...
- [struts2学习笔记] 第二节 使用Maven搞定管理和构造Struts 2 Web应用程序的七个步骤
本文地址:http://blog.csdn.net/sushengmiyan/article/details/40303897 官方文档:http://struts.apache.org/releas ...
- struts2学习笔记之二:基本环境搭建
学习struts2有一段时间了,作为一个运维人员学习的时间还是挺紧张的,写这篇文件为了方便以后复习时使用 环境: MyEclipse 10 tomcat6 jdk1.6 首先建立一个web项目,并 ...
- 【Struts2学习笔记-4】包含其他配置文件
包含其他配置文件 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLI ...
- 【Struts2学习笔记-3】常量配置
Struts2常量 配置Struts2常量值有3个地方,1)在struts.properties文件中配置常量:2)在web.xml文件中配置FileterDispatcher指定初始化参数来配置常量 ...
- struts2学习笔记(4)——数据类型转换
回过头来看昨天的那个例子. 在昨天的例子中,只转换了一个Point类,如果想转换多个Point类怎么办呢?在昨天的例子上面做一个小的修改. 首先在input.jsp页面中修改几个输入框. <s: ...
随机推荐
- 在Unity3D中实现安卓平台的本地通知推送
[前言] 对于手游来说,什么时候需要推送呢?玩过一些带体力限制的游戏就会发现,我的体力在恢复满后,手机会收到一个通知告诉我体力已完全恢复了.这类通知通常是由本地的客户端发起的,没有经过服务端. 在安卓 ...
- Bootstrap入门(二十四)data属性
Bootstrap入门(二十四)data属性 你可以仅仅通过 data 属性 API 就能使用所有的 Bootstrap 插件,无需写一行 JavaScript 代码.这是 Bootstrap 中的一 ...
- UWP必备知识:App File Explorer
由来 应用在手机端出问题时如果查看LocalState文件夹的数据库文件与日志文件 如何查看应用在手机端占用带宽与占用CPU内存情况 介绍 [UWP开发之Mvvmlight实践七:如何查找设备(Mob ...
- CodeForces758D
D. Ability To Convert time limit per test:1 second memory limit per test:256 megabytes input:standar ...
- Javascript/js的相等和不等运算符(= 、== 、===)
"=="和"==="运算符用于比较两个值是否相等,当然它们对相等的定义不尽相同.两个运算符允许任意类型的操作数,如果操作数相等则返回tru,否则返回false. ...
- 《JAVASCRIPT高级程序设计》第五章(1)
引用类型是一种将数据和功能组合到一起的数据结构,它与类相似,但是是不同的概念:ECMAScript虽然是一门面向对象的语言,但它不具备传统的面向对象语言所支持的类和结构等基本结构.引用类型也被称为“对 ...
- [CSS3] 学习笔记-CSS3常用操作
1.对齐操作 使用margin属性进行水平对齐:使用position进行左右对齐:使用float属性进行左右对齐. <!doctype html> <html> <hea ...
- ADO.NET 防止SQL注入
规避SQL注入 如果不规避,在黑窗口里面输入内容时利用拼接语句可以对数据进行攻击 如:输入Code值 p001' union select * from Info where '1'='1 //这样可 ...
- make clean指令出现问题
今天第一次使用make指令,没搞懂make clean就直接使用了,结果发现如下错误问题:make: *** No rule to make target 'clear'. 停止. 最后的找了半天有下 ...
- css3 过渡和2d变换——回顾
1.transition 语法:transition: property duration timing-function delay; transition-property 设置过渡效果的css ...