JavaShuo
栏目
标签
Struts 2的基石——拦截器(Interceptor)
时间 2019-11-24
标签
struts
基石
拦截
interceptor
栏目
Struts
繁體版
原文
原文链接
首先,要跟你们道个歉,前一阵子为给客户个一个DEMO,忙得不可开交,因此好久没有更新Blog。提到这个DEMO我想顺便跟你们分享一下心得——若是你们但愿快速开发,一个相似Struts 2这样的简单方便的WEB框架必不可少。咱们在开发DEMO使用的仍是Struts 1.2.8,并且没有不使用任何EL(表达式语言),致使页面出现无数相似“<%= ((Integer) request.getAttribute("xx")).intValue()%6 %>”的代码。Struts 1.x的Form Bean的麻烦使得有部分同事直接使用request.getParameter(String arg),继而引入另外一种麻烦。诸如此类的问题,在DEMO这样时间紧迫的项目凸显了Struts 1.x对快速开发的无能为力。不过没办法,因为咱们项目中的几个资深员工除了Struts 1.x外,对其它的WEB框架彷佛不大感兴趣。
言归正传,Interceptor(如下译为拦截器)是Struts 2的一个强有力的工具,有许多功能(feature)都是构建于它之上,如
国际化
、
转换器
,
校验
等。
什么是拦截器
拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问以前,进行拦截而后在以前或以后加入某些操做。拦截是AOP的一种实现策略。
在Webwork的中文文档的解释为——拦截器是动态拦截Action调用的对象。它提供了一种机制可使开发者能够定义在一个action执行的先后执行的代码,也能够在一个action执行前阻止其执行。同时也是提供了一种能够提取action中可重用的部分的方式。
谈到拦截器,还有一个词你们应该知道——拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈Interceptor Stack)。拦截器链就是将拦截器按必定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其以前定义的顺序被调用。
实现原理
Struts 2的拦截器实现相对简单。当请求到达Struts 2的ServletDispatcher时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,而后串成一个列表(list),最后一个一个地调用列表中的拦截器,如图1所示。
图1 拦截器调用序列图
已有的拦截器
Struts 2已经为您提供丰富多样的,功能齐全的拦截器实现。你们能够到struts2-all-2.0.1.jar或struts2-core-2.0.1.jar包的struts-default.xml查看关于默认的拦截器与拦截器链的配置。
在本文使用是Struts 2的最新发布版本2.0.1。须要下载的朋友请点击如下连接:
[url]http://apache.justdn.org/struts/binaries/struts-2.0.1-all.zip[/url]
如下部分就是从struts-default.xml文件摘取的内容:
<
interceptor
name
="alias"
class
="com.opensymphony.xwork2.interceptor.AliasInterceptor"
/>
<
interceptor
name
="autowiring"
class
="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"
/>
<
interceptor
name
="chain"
class
="com.opensymphony.xwork2.interceptor.ChainingInterceptor"
/>
<
interceptor
name
="conversionError"
class
="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"
/>
<
interceptor
name
="createSession"
class
="org.apache.struts2.interceptor.CreateSessionInterceptor"
/>
<
interceptor
name
="debugging"
class
="org.apache.struts2.interceptor.debugging.DebuggingInterceptor"
/>
<
interceptor
name
="external-ref"
class
="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor"
/>
<
interceptor
name
="execAndWait"
class
="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"
/>
<
interceptor
name
="exception"
class
="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"
/>
<
interceptor
name
="fileUpload"
class
="org.apache.struts2.interceptor.FileUploadInterceptor"
/>
<
interceptor
name
="i18n"
class
="com.opensymphony.xwork2.interceptor.I18nInterceptor"
/>
<
interceptor
name
="logger"
class
="com.opensymphony.xwork2.interceptor.LoggingInterceptor"
/>
<
interceptor
name
="model-driven"
class
="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"
/>
<
interceptor
name
="scoped-model-driven"
class
="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"
/>
<
interceptor
name
="params"
class
="com.opensymphony.xwork2.interceptor.ParametersInterceptor"
/>
<
interceptor
name
="prepare"
class
="com.opensymphony.xwork2.interceptor.PrepareInterceptor"
/>
<
interceptor
name
="static-params"
class
="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"
/>
<
interceptor
name
="scope"
class
="org.apache.struts2.interceptor.ScopeInterceptor"
/>
<
interceptor
name
="servlet-config"
class
="org.apache.struts2.interceptor.ServletConfigInterceptor"
/>
<
interceptor
name
="sessionAutowiring"
class
="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor"
/>
<
interceptor
name
="timer"
class
="com.opensymphony.xwork2.interceptor.TimerInterceptor"
/>
<
interceptor
name
="token"
class
="org.apache.struts2.interceptor.TokenInterceptor"
/>
<
interceptor
name
="token-session"
class
="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"
/>
<
interceptor
name
="validation"
class
="com.opensymphony.xwork2.validator.ValidationInterceptor"
/>
<
interceptor
name
="workflow"
class
="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"
/>
<
interceptor
name
="store"
class
="org.apache.struts2.interceptor.MessageStoreInterceptor"
/>
<
interceptor
name
="checkbox"
class
="org.apache.struts2.interceptor.CheckboxInterceptor"
/>
<
interceptor
name
="profiling"
class
="org.apache.struts2.interceptor.ProfilingActivationInterceptor"
/>
配置和使用拦截器
在struts-default.xml中已经配置了以上的拦截器。若是您想要使用上述拦截器,只须要在应用程序struts.xml文件中经过“<include file="struts-default.xml" />”将struts-default.xml文件包含进来,并继承其中的struts-default包(package),最后在定义Action时,使用“<interceptor-ref name="xx" />”引用拦截器或拦截器栈(interceptor stack)。一旦您继承了struts-default包(package),全部Action都会调用拦截器栈 ——defaultStack。固然,在Action配置中加入“<interceptor-ref name="xx" />”能够覆盖defaultStack。
下面是关于拦截器timer使用的例子。首先,新建Action类tuotrial/TimerInterceptorAction.java,内容以下:
package
tutorial;
import
com.opensymphony.xwork2.ActionSupport;
public
class
TimerInterceptorAction
extends
ActionSupport
{
@Override
public
String execute()
{
try
{
//
模拟耗时的操做
Thread.sleep(
500
);
}
catch
(Exception e)
{
e.printStackTrace();
}
return
SUCCESS;
}
}
配置Action,名为Timer,配置文件以下:
<!
DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd"
>
<
struts
>
<
include
file
="struts-default.xml"
/>
<
package
name
="InterceptorDemo"
extends
="struts-default"
>
<
action
name
="Timer"
class
="tutorial.TimerInterceptorAction"
>
<
interceptor-ref
name
="timer"
/>
<
result
>
/Timer.jsp
</
result
>
</
action
>
</
package
>
</
struts
>
至于Timer.jsp能够随意写些什么到里面。发布运行应用程序,在浏览器的地址栏键入
[url]http://localhost:8080/Struts2_Interceptor/Timer.action[/url]
,在出现Timer.jsp页面后,查看服务器的后台输出。
2006
-
12
-
6
14
:
27
:
32
com.opensymphony.xwork2.interceptor.TimerInterceptor doLog
信息: Executed action
[
//Timer!execute
]
took
2859
ms.
在您的环境中执行Timer!execute的耗时,可能上述的时间有些不一样,这取决于您PC的性能。可是不管如何,2859 ms与500 ms仍是相差太远了。这是什么缘由呢?其实缘由是第一次加载Timer时,须要进行必定的初始工做。当你从新请求Timer.action时,以上输出会变为:
2006
-
12
-
6
14
:
29
:
18
com.opensymphony.xwork2.interceptor.TimerInterceptor doLog
信息: Executed action
[
//Timer!execute
]
took
500
ms.
OK,这正是咱们期待的结果。上述例子演示了拦截器timer的用途——用于显示执行某个action方法的耗时,在咱们作一个粗略的性能调试时,这至关有用。
自定义拦截器
做为“框架(framework)”,可扩展性是不可或缺的,由于世上没有放之四海而皆准的东西。虽然,Struts 2为咱们提供如此丰富的拦截器实现,可是这并不意味咱们失去建立自定义拦截器的能力,偏偏相反,在Struts 2自定义拦截器是至关容易的一件事。
你们在开始着手建立自定义拦截器前,切记如下原则:
拦截器必须是无状态的,不要使用在API提供的ActionInvocation以外的任何东西。
要求拦截器是无状态的缘由是Struts 2不能保证为每个请求或者action建立一个实例,因此若是拦截器带有状态,会引起并发问题。
全部的Struts 2的拦截器都直接或间接实现接口com.opensymphony.xwork2.interceptor.Interceptor。除此以外,你们可能更喜欢继承类com.opensymphony.xwork2.interceptor.AbstractInterceptor。
如下例子演示经过继承AbstractInterceptor,实现受权拦截器。
首先,建立受权拦截器类tutorial.AuthorizationInterceptor,代码以下:
package
tutorial;
import
java.util.Map;
import
com.opensymphony.xwork2.Action;
import
com.opensymphony.xwork2.ActionInvocation;
import
com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public
class
AuthorizationInterceptor
extends
AbstractInterceptor
{
@Override
public
String intercept(ActionInvocation ai)
throws
Exception
{
Map session
=
ai.getInvocationContext().getSession();
String role
=
(String) session.get(
"
ROLE
"
);
if
(
null
!=
role)
{
Object o
=
ai.getAction();
if
(o
instanceof
RoleAware)
{
RoleAware action
=
(RoleAware) o;
action.setRole(role);
}
return
ai.invoke();
}
else
{
return
Action.LOGIN;
}
}
}
以上代码至关简单,咱们经过检查session是否存在键为“ROLE”的字符串,判断用户是否登录。若是用户已经登录,将角色放到Action中,调用Action;不然,拦截直接返回Action.LOGIN字段。为了方便将角色放入Action,我定义了接口tutorial.RoleAware,代码以下:
package
tutorial;
public
interface
RoleAware
{
void
setRole(String role);
}
接着,建立Action类tutorial.AuthorizatedAccess模拟访问受限资源,它做用就是经过实现RoleAware获取角色,并将其显示到ShowUser.jsp中,代码以下:
package
tutorial;
import
com.opensymphony.xwork2.ActionSupport;
public
class
AuthorizatedAccess
extends
ActionSupport
implements
RoleAware
{
private
String role;
public
void
setRole(String role)
{
this
.role
=
role;
}
public
String getRole()
{
return
role;
}
@Override
public
String execute()
{
return
SUCCESS;
}
}
如下是ShowUser.jsp的代码:
<%
@ page contentType
=
"
text/html; charset=UTF-8
"
%>
<%
@taglib prefix
=
"
s
"
uri
=
"
/struts-tags
"
%>
<
html
>
<
head
>
<
title
>
Authorizated User
</
title
>
</
head
>
<
body
>
<
h1
>
Your role is:
<
s:property
value
="role"
/></
h1
>
</
body
>
</
html
>
而后,建立tutorial.Roles初始化角色列表,代码以下:
package
tutorial;
import
java.util.Hashtable;
import
java.util.Map;
public
class
Roles
{
public
Map
<
String, String
>
getRoles()
{
Map
<
String, String
>
roles
=
new
Hashtable
<
String, String
>
(
2
);
roles.put(
"
EMPLOYEE
"
,
"
Employee
"
);
roles.put(
"
MANAGER
"
,
"
Manager
"
);
return
roles;
}
}
接下来,新建Login.jsp实例化tutorial.Roles,并将其roles属性赋予<s:radio>标志,代码以下:
<%
@ page contentType
=
"
text/html; charset=UTF-8
"
%>
<%
@taglib prefix
=
"
s
"
uri
=
"
/struts-tags
"
%>
<
html
>
<
head
>
<
title
>
Login
</
title
>
</
head
>
<
body
>
<
h1
>
Login
</
h1
>
Please select a role below:
<
s:bean
id
="roles"
name
="tutorial.Roles"
/>
<
s:form
action
="Login"
>
<
s:radio
list
="#roles.roles"
value
="'EMPLOYEE'"
name
="role"
label
="Role"
/>
<
s:submit
/>
</
s:form
>
</
body
>
</
html
>
建立Action类tutorial.Login将role放到session中,并转到Action类tutorial.AuthorizatedAccess,代码以下:
package
tutorial;
import
java.util.Map;
import
org.apache.struts2.interceptor.SessionAware;
import
com.opensymphony.xwork2.ActionSupport;
public
class
Login
extends
ActionSupport
implements
SessionAware
{
private
String role;
private
Map session;
public
String getRole()
{
return
role;
}
public
void
setRole(String role)
{
this
.role
=
role;
}
public
void
setSession(Map session)
{
this
.session
=
session;
}
@Override
public
String execute()
{
session.put(
"
ROLE
"
, role);
return
SUCCESS;
}
}
最后,配置struts.xml文件,内容以下:
<!
DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd"
>
<
struts
>
<
include
file
="struts-default.xml"
/>
<
package
name
="InterceptorDemo"
extends
="struts-default"
>
<
interceptors
>
<
interceptor
name
="auth"
class
="tutorial.AuthorizationInterceptor"
/>
</
interceptors
>
<
action
name
="Timer"
class
="tutorial.TimerInterceptorAction"
>
<
interceptor-ref
name
="timer"
/>
<
result
>
/Timer.jsp
</
result
>
</
action
>
<
action
name
="Login"
class
="tutorial.Login"
>
<
result
type
="chain"
>
AuthorizatedAccess
</
result
>
</
action
>
<
action
name
="AuthorizatedAccess"
class
="tutorial.AuthorizatedAccess"
>
<
interceptor-ref
name
="auth"
/>
<
result
name
="login"
>
/Login.jsp
</
result
>
<
result
name
="success"
>
/ShowRole.jsp
</
result
>
</
action
>
</
package
>
</
struts
>
发布运行应用程序,在浏览器地址栏中输入:
[url]http://localhost:8080/Struts2_Interceptor/AuthorizatedAccess.action[/url]
。因为此时,session尚未键为“ROLE”的值,因此返回Login.jsp页面,如图2所示:
图2 Login.jsp
选中Employee,点击Submit,出现图3所示页面:
图3 ShowRole.jsp
总结
拦截器是Struts 2比较重要的一个功能。经过正确地使用拦截器,咱们能够编写高可复用的代码。
相关文章
1.
Struts 2的基石——拦截器(Interceptor)
2.
Struts 2的基石——拦截器(Interceptor)
3.
Interceptor拦截器
4.
Struts2的基石--拦截器
5.
Struts2拦截器(Interceptor)
6.
interceptor拦截器
7.
基于Struts 2 拦截器实现
8.
Struts 拦截器 、
9.
struts——拦截器
10.
Struts 拦截器
更多相关文章...
•
Mybatis实现映射器的2种方式
-
MyBatis教程
•
QBC的2种检索方式
-
Hibernate教程
•
☆基于Java Instrument的Agent实现
•
Docker容器实战(七) - 容器眼光下的文件系统
相关标签/搜索
sql拦截器
拦截器
validation拦截器
拦截
Restful和拦截器
登录拦截器
interceptor
基石
过滤器与拦截器的区别
Struts
浏览器信息
Docker教程
Docker命令大全
服务器
0
分享到微博
分享到微信
分享到QQ
每日一句
每一个你不满意的现在,都有一个你没有努力的曾经。
最新文章
1.
添加voicebox
2.
Java 8u40通过Ask广告软件困扰Mac用户
3.
数字图像处理入门[1/2](从几何变换到图像形态学分析)
4.
如何调整MathType公式的字体大小
5.
mAP_Roi
6.
GCC编译器安装(windows环境)
7.
LightGBM参数及分布式
8.
安装lightgbm以及安装xgboost
9.
开源matpower安装过程
10.
从60%的BI和数据仓库项目失败,看出从业者那些不堪的乱象
本站公众号
欢迎关注本站公众号,获取更多信息
相关文章
1.
Struts 2的基石——拦截器(Interceptor)
2.
Struts 2的基石——拦截器(Interceptor)
3.
Interceptor拦截器
4.
Struts2的基石--拦截器
5.
Struts2拦截器(Interceptor)
6.
interceptor拦截器
7.
基于Struts 2 拦截器实现
8.
Struts 拦截器 、
9.
struts——拦截器
10.
Struts 拦截器
>>更多相关文章<<