Struts2 拦截器配置以及实现
@(Java ThirdParty)[Struts|Interceptor]
Struts2 拦截器配置以及实现
Struts2的拦截器应用于Action,可以在执行Action的方法之前,之后或者两者。用于处理一些公共的方法,而不影响原有的代码,并且使得可以关注功能的实现,分离关注点。比如防止重复提交等。
如下图(图片来自Struts2文档Interceptor章节):
拦截器配置
注:以下配置均来自于Struts2官方的例子
Struts2内置了一些拦截器,也可以通过实现Interceptor
接口来自定义拦截器。
如下,在struts.xml中配置自定义拦截器以及引用定义的拦截器:
<package name="default" extends="struts-default">
<interceptors>
<interceptor name="timer" class=".."/>
</interceptors>
<action name="login"
class="tutorial.Login">
<interceptor-ref name="timer"/>
<result name="input">login.jsp</result>
</action>
</package>
如果定义多个拦截器,像上面那样一个个引用显然是很费劲的,这里可以将多个打包为一个拦截器栈,直接引用该拦截器栈即可:
<package name="default" extends="struts-default">
<interceptors>
<interceptor name="timer" class=".."/>
<interceptor name="logger" class=".."/>
<interceptor-stack name="myStack">
<interceptor-ref name="timer"/>
<interceptor-ref name="logger"/>
</interceptor-stack>
</interceptors>
<action name="login"
class="tutuorial.Login">
<interceptor-ref name="myStack"/>
<result name="input">login.jsp</result>
</action>
</package>
Struts2 拦截器实现
在先介绍Struts2拦截器实现时,需要先介绍一个设计模式,拦截过滤器,Struts2采用了该设计模式来实现,文档中注解了说明是使用Command设计模式,但是我觉得用Intercepting filter来理解比较好理解。
Intercepting filter pattern
在wiki中Intercepting Filter定义为:JavaEE设计模式,用于创建可插拔式过滤器,用于处理通用的服务,而不需要改变和兴请求的处理代码。这涉及了四个组件:Filter Manager,Filter chain,Filters,Target。如下:
在下图,可以看成FilterManager维护着一系列的Filter,并且知道Target,这里可以实现为:FilterManager内部维护一个List<Filter>
,该List作为Filter Chain。
注:图片来自Wiki
处理流程如下:
注:图片来自Wiki
Struts2 拦截器实现
Struts2中DefaultActionInvocation
可以看做一个FilterManager,其中有Iterator<InterceptorMapping>
,可以看做FilterChain,即包含了所有需要拦截该Action的Interceptor,其中Object action
为真正的Target。如下图:
Interceptor接口:
public interface Interceptor extends Serializable {
void destroy();
void init();
String intercept(ActionInvocation invocation) throws Exception;
}
主要执行流程在DefaultActionInvocation.invoke
方法中,该方法用递归来实现链式调用(和Tomcat中实现FIlter一样):
public String invoke() throws Exception {
// 省略了部分代码...
// 如果还有Interceptor,则继续(递归条件)
if (interceptors.hasNext()) {
try {
// 获取拦截器,并将当前对象传递给拦截器,由拦截器决定是要需要继续执行,例如:invocation.invoke(),如果执行了,则继续递归,直到执行完所有的拦截器,如果没有调用该方法,即拦截了,则这里就终止递归了。
resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);
}
finally {
UtilTimerStack.pop(interceptorMsg);
}
} else {
// 只有执行完所有拦截器,才执行Action的方法
resultCode = invokeActionOnly();
}
}
Tomcat Filter实现
Tomcat中Filter的实现和上面差不多,不过其中的类名和概念的名称比较匹配。如下:
ApplicationDispatcher
通过使用FilterChain
来实现Filter链式调用。
其中ApplicationFIlterChain.internalDoFilter
为核心的代码:
private void internalDoFilter(ServletRequest request,
ServletResponse response)
throws IOException, ServletException {
// 通过pos来记录当前执行的Filter,只有到所有Filter执行完(递归终止条件之一)
if (pos < n) {
ApplicationFilterConfig filterConfig = filters[pos++];
Filter filter = null;
try {
filter = filterConfig.getFilter();
if (request.isAsyncSupported() && "false".equalsIgnoreCase(
filterConfig.getFilterDef().getAsyncSupported())) {
// ...
} else {
// Filter.doFilter,通过传入当前对象,来实现递归调用,将控制权传递给Filter,由Filter来决定是否需要继续执行下去
filter.doFilter(request, response, this);
}
return;
}
try {
if ((request instanceof HttpServletRequest) &&
(response instanceof HttpServletResponse)) {
if( Globals.IS_SECURITY_ENABLED ) {
// ...
} else {
// 执行Target真正的方法
servlet.service(request, response);
}
} else {
servlet.service(request, response);
}
}
// ...
}
参考文档:
Wiki:
https://en.wikipedia.org/wiki/Intercepting_filter_pattern
https://en.wikipedia.org/wiki/Interceptor_pattern
官方文档:
http://struts.apache.org/docs/interceptors.html
Struts2 拦截器配置以及实现的更多相关文章
- Struts2拦截器配置
1. 理解拦截器 1.1. 什么是拦截器: 拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作.拦截是AO ...
- Struts2拦截器配置实例
拦截器介绍 拦截器 的使用 ,源自Spring AOP(面向切面编程)思想 拦截器 采用 责任链 模式 * 在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链. * 责任链每一个节 ...
- struts2 拦截器配置
CheckLoginInterceptor.java---拦截器具体实现类: package com.sunhoo.hcpms.struts2.action.interceptors; import ...
- 转载 - Struts2拦截器配置
出处:http://blog.csdn.net/axin66ok/article/details/7321430 目录(?)[-] 理解拦截器 1 什么是拦截器 2 拦截器的实现原理 拦截器的配置 使 ...
- struts2拦截器配置;拦截器栈;配置默认拦截器;拦截方法的拦截器MethodFilterInterceptor;完成登录验证
struts2.xml 内容 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts ...
- Struts2拦截器配置和使用
拦截器是Struts2最强大的特性之一,它是一种可以让用户在Action执行之前和Result执行之后进行一些功能处理的机制. 说到拦截器interceptor,就会想到过滤器filter: 过滤器f ...
- Struts2 拦截器配置及使用
在我的项目中有个需求,实现记录用户操作的系统日志,基于这个功能我首先想到的是Struts 的拦截器.配置一个全部Action都会拦截的拦截,写一个公用的服务.每当用户发送请求到Action 就记录相应 ...
- struts2拦截器interceptor的三种配置方法
1.struts2拦截器interceptor的三种配置方法 方法1. 普通配置法 <struts> <package name="struts2" extend ...
- struts2拦截器interceptor的配置方法及使用
转: struts2拦截器interceptor的配置方法及使用 (2015-11-09 10:22:28) 转载▼ 标签: it 365 分类: Struts2 NormalText Code ...
随机推荐
- 突然想到一个问题:有关 cqrs 分离
大部分的系统,都是查询多,c少,那为什么我们不把q放在内存里面,而c直接操作数据库呢? 就如enode,c在内存,而q在数据库,当然q也很容易扩展到内存缓存上.二个enode案例demo,都可以让c的 ...
- shell 1>&2 2>&1 &>filename重定向的含义和区别
当初在shell中, 看到">&1"和">&2"始终不明白什么意思.经过在网上的搜索得以解惑.其实这是两种输出. 在 shell 程 ...
- Jmeter+TCP\Scoket(8583)报文压力测试
Jmeter一般被用来测试HTTP协议,我第一次拿来测试socket协议,pos机传输报文为8583,协议属于socket,也是TCP协议的一种,网上有LR怎么测试8583报文,我就研究了一下怎么用J ...
- 项目游戏开发日记 No.0x000006(Finish)
项目开发的最后一周! 突然一下就把游戏收尾了, 就像一个嘎然而止的乐章, 留下的, 是无尽的回味. 余音绕梁的夜晚, 也还想着, 拼命码代码的日子, 和还留在嘴里回味的烈酒的浓香. ————————— ...
- Spring 事务详解
实现购买股票案例: 一.引入JAR文件: 二.开始搭建分层架构---创建账户(Account)和股票(Stock)实体类 Account: ? 1 2 3 4 5 6 7 8 9 10 11 12 1 ...
- PAT 1049. 数列的片段和(20)
给定一个正数数列,我们可以从中截取任意的连续的几个数,称为片段.例如,给定数列{0.1, 0.2, 0.3, 0.4},我们有(0.1) (0.1, 0.2) (0.1, 0.2, 0.3) (0.1 ...
- codevs 3288 积木大赛
题目描述 Description 春春幼儿园举办了一年一度的"积木大赛".今年比赛的内容是搭建一座宽度为 n 的大厦,大厦可以看成由 n 块宽度为1的积木组成,第i块积木的最终高度 ...
- 21-Python-Django进阶补充篇
1. 路由部分补充 1.1 默认值 url: url(r'^index/', views.index, {'name': 'root'}), views: def index(request,name ...
- 【第四篇】ASP.NET MVC快速入门之完整示例(MVC5+EF6)
目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...
- poj 1251 Jungle Roads (最小生成树)
poj 1251 Jungle Roads (最小生成树) Link: http://poj.org/problem?id=1251 Jungle Roads Time Limit: 1000 ...