盐城疝气哪家医院好:struts2.x中的拦截器
来源:百度文库 编辑:偶看新闻 时间:2024/05/04 06:20:05
拦截器:Interceptor。指在执行某一方法之前或之后做一些东西。与servlet里面的filter过滤器是很类似。拦截器本身就是一个普通的类。
拦截器:就是在调用action的过程中插入自己想加入的逻辑
问题引入:假如有一业务需求
如果用户登录后,就可以访问action中的所有方法;
如果用户没有登录,就不允许访问action中的方法,并且提示"你没有权限执行该是操作"
要自定义拦截器需要实现com.opensymphony.xwork2.interceptor.Interceptor接口
一旦定义了拦截器和拦截器栈后,就可以使用这个拦截器或拦截器栈来拦截Action了。拦截器的拦截行为将会在Action的exceute方法执行之前被执行
在struts.xml文件中定义拦截器,拦截器栈:
......
3. 使用拦截器
一旦定义了拦截器和拦截器栈后,就可以使用这个拦截器或拦截器栈来拦截Action了。拦截器的拦截行为将会在Action的exceute方法执行之前被执行。
此处需要注意的是,如果为Action指定了一个拦截器,则系统默认的拦截器栈将会失去作用。为了继续使用默认拦截器,所以上面配置文件中手动引入了默认拦截器。
******************************************************************************************************************************************************************************
拦截器:与过滤器非常相似,都是一个接口,该接口中都有两个相同的方法init(),destory()这两个方法仅被执行一次,主方法不同,它会被执行多次。
假如有这样一个业务:如果用户登录后,则可以访问action中的所有方法;如果用户没有登录,则不允许访问action中的方法,并且提示“你没有权限执行该项操作”
实现:
第1步:
自定义拦截器需要实现com.opensymphony.xwork2.interceptor.Interceptor接口。
public Permission implements Interceptor{
public void destory(){}
public void init(){}
public String intercept(ActionInvocation invocation) throws Exception{
System.out.println("进入拦截器");
if(session里存在用户){
String result=invocation.invoke();
}else{
return "logon";
}
}
}
第2步:在struts.xml中配置:
因为struts2中,如对文件上传,数据验证,封装请求参数到action等功能都是由系统默认的defaultStack中
的拦截器实现的,所以,我们定义的拦截器要引用系统默认的defaultStack,这样,应用才可以使用struts2框
架提供的众多功能。
如果希望包下面的所有action都使用自定义的拦截器,可以通过
把拦截器定义为默认拦截器。注意:每个包只能指定一个默认的的拦截器,另外,一旦我们为该包中的某个action显示
地指定了某个拦截器,则默认拦截器不会起作用。
*****************************************************************************************************************************************************************************
Struts2的基石——拦截器(Interceptor)
Interceptor(以下译为拦截器)是Struts 2的一个强有力的工具,有许多功能(feature)都是构建于它之上,如国际化、转换器,校验等。什么是拦截器
拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。
在Webwork的中文文档的解释为——拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式。
谈到拦截器,还有一个词大家应该知道——拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
实现原理
Struts2的拦截器实现相对简单。当请求到达Struts 2的ServletDispatcher时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表(list),最后一个一个地调用列表中的拦截器,如图1所示。
图1 拦截器调用序列图已有的拦截器
Struts2已经为您提供丰富多样的,功能齐全的拦截器实现。大家可以到struts2-all-2.0.1.jar或struts2-core-2.0.1.jar包的struts-default.xml查看关于默认的拦截器与拦截器链的配置。
在本文使用是Struts 2的2.0.1版本。需要下载的朋友请点击以下链接:
http://apache.justdn.org/struts/binaries/struts-2.0.1-all.zip
以下部分就是从struts-default.xml文件摘取的内容:
< interceptor name ="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
< interceptorname ="autowiring"class ="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
< interceptorname ="chain"class ="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
< interceptorname ="conversionError"class ="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>
< interceptorname ="createSession"class ="org.apache.struts2.interceptor.CreateSessionInterceptor"/>
< interceptorname ="debugging"class ="org.apache.struts2.interceptor.debugging.DebuggingInterceptor"/>
< interceptorname ="external-ref"class ="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor"/>
< interceptorname ="execAndWait"class ="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>
< interceptorname ="exception"class ="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>
< interceptorname ="fileUpload"class ="org.apache.struts2.interceptor.FileUploadInterceptor"/>
< interceptorname ="i18n"class ="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>
< interceptorname ="logger"class ="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
< interceptorname ="model-driven"class ="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
< interceptorname ="scoped-model-driven"class ="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
< interceptorname ="params"class ="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
< interceptorname ="prepare"class ="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
< interceptorname ="static-params"class ="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
< interceptorname ="scope"class ="org.apache.struts2.interceptor.ScopeInterceptor"/>
< interceptorname ="servlet-config"class ="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
< interceptorname ="sessionAutowiring"class ="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor"/>
< interceptorname ="timer"class ="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
< interceptorname ="token"class ="org.apache.struts2.interceptor.TokenInterceptor"/>
< interceptorname ="token-session"class ="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
< interceptorname ="validation"class ="com.opensymphony.xwork2.validator.ValidationInterceptor"/>
< interceptorname ="workflow"class ="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
< interceptorname ="store"class ="org.apache.struts2.interceptor.MessageStoreInterceptor"/>
< interceptorname ="checkbox"class ="org.apache.struts2.interceptor.CheckboxInterceptor"/>
< interceptorname ="profiling"class ="org.apache.struts2.interceptor.ProfilingActivationInterceptor"/>
配置和使用拦截器
在struts-default.xml中已经配置了以上的拦截器。如果您想要使用上述拦截器,只需要在应用程序struts.xml文件中通过 “
下面是关于拦截器timer使用的例子。首先,新建Action类tuotrial/TimerInterceptorAction.java,内容如下:
package tutorial;
import com.opensymphony.xwork2.ActionSupport;
public class TimerInterceptorAction extendsActionSupport {
@Override
public Stringexecute() {
try {
// 模拟耗时的操作
Thread.sleep( 500);
} catch (Exception e) {
e.printStackTrace();
}
return SUCCESS;
}
}
配置Action,名为Timer,配置文件如下:
"-//Apache Software Foundation//DTD StrutsConfiguration 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" >
action >
package >
struts>
至于Timer.jsp可以随意写些什么到里面。发布运行应用程序,在浏览器的地址栏键入http://localhost:8080/Struts2_Interceptor/Timer.action,在出现Timer.jsp页面后,查看服务器的后台输出。
2006 - 12 - 6 14 : 27 : 32 com.opensymphony.xwork2.interceptor.TimerInterceptordoLog
信息: Executed action [ //Timer!execute] took 2859ms.
在您的环境中执行Timer!execute的耗时,可能上述的时间有些不同,这取决于您PC的性能。但是无论如何,2859 ms与500 ms还是相差太远了。这是什么原因呢?其实原因是第一次加载Timer时,需要进行一定的初始工作。当你重新请求Timer.action时,以上输出会 变为:
2006 - 12 - 6 14 : 29 : 18 com.opensymphony.xwork2.interceptor.TimerInterceptordoLog
信息: Executed action [ //Timer!execute] took 500ms.
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 extendsAbstractInterceptor {
@Override
public Stringintercept(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);
}
returnai.invoke();
} else {
returnAction.LOGIN;
}
}
}
以上代码相当简单,我们通过检查session是否存在键为“ROLE”的字符串,判断用户是否登陆。如果用户已经登陆,将角色放到Action 中,调用Action;否则,拦截直接返回Action.LOGIN字段。为了方便将角色放入Action,我定义了接口 tutorial.RoleAware,代码如下:
package tutorial;
public interface RoleAware {
void setRole(Stringrole);
}
接着,创建Action类tutorial.AuthorizatedAccess模拟访问受限资源,它作用就是通过实现RoleAware获取角色,并将其显示到ShowUser.jsp中,代码如下:
package tutorial;
import com.opensymphony.xwork2.ActionSupport;
public class AuthorizatedAccess extendsActionSupport implementsRoleAware {
private Stringrole;
public void setRole(String role) {
this .role = role;
}
public StringgetRole() {
return role;
}
@Override
public Stringexecute() {
return SUCCESS;
}
}
以下是ShowUser.jsp的代码:
<% @ page contentType= " text/html; charset=UTF-8 " %>
<% @taglib prefix = "s " uri = "/struts-tags " %>
< html>
< head>
< title > Authorizated User
head>
< body>
< h1 > Your role is: < s:property value ="role" />
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属性赋予
<% @ 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 implementsSessionAware {
private Stringrole;
private Mapsession;
public StringgetRole() {
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文件,内容如下:
"-//Apache Software Foundation//DTD StrutsConfiguration 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 >
interceptors >
< action name ="Timer" class="tutorial.TimerInterceptorAction" >
action >
< action name ="Login" class="tutorial.Login" >
action >
< action name ="AuthorizatedAccess" class ="tutorial.AuthorizatedAccess">
action >
package >
struts>
发布运行应用程序,在浏览器地址栏中输入:http://localhost:8080/Struts2_Interceptor/AuthorizatedAccess.action。由于此时,session还没有键为“ROLE”的值,所以返回Login.jsp页面,如图2所示:
图2 Login.jsp选中Employee,点击Submit,出现图3所示页面:
图3 ShowRole.jsp总结
拦截器是Struts 2比较重要的一个功能。通过正确地使用拦截器,我们可以编写高可复用的代码。