全部博文(2065)
分类: Java
2010-06-14 22:30:04
最基础的---拦截器
如果想做DEMO的话快速开发的话我们就可以使用这样的一种WEB框架。能够快速实现开发工作!要保持对技术的敏感与更新哦。要多学习新的框架技术提高开发的速度!
一、什么是拦截器
拦截器AOP中用于在某个方法或字段被访问之间,进行拦截然后在之前或之后加入某些操作进来。拦截就是AOP的一种实现策略。
拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者定义在一个action执行前后执行的代码,也可以在一个action执行前阻止其执行。
谈到拦截器,还有一个词大家应该知道——拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
(相当于定义了多个拦截器的一个组合一起进行拦截它!)
实现原理
当请求到达Struts 2的ServletDispatcher时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表(list),最后一个一个地调用列表中的拦截器,如图1所示。
即在Action之前定义一组多个拦截器。然后再丢给Action处理。处理之后将结果Result返回给客户端去。
目前已有的拦截器
< 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中已经配置了以上的拦截器。
<package name="IOCDemo"
extends="struts-default"> 哦原来继承的原因是它老人家自己定义了好多的拦截器与过滤器之类 的东西的!
如果您想要使用上述拦截器,只需要在应用程序struts.xml文件中通过“
1、 包含进来
2、 包还是继承吧<package name="IOCDemo" extends="struts-default">
3、 使用了
以下示例是一个拦截器timer的使用
第一步:编写拦截器类
package tutorial;
import com.opensymphony.xwork2.ActionSupport;
public class TimerInterceptorAction extends ActionSupport {
@Override
public String
execute() {
try {
//模拟耗时的操作
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return SUCCESS;
}
}
第二步:配置拦截器
<struts>
<include file="struts-default.xml"/>这个得包含进来才行的!
<package name="InterceptorDemo"
extends="struts-default">
<action name="Timer" class="tutorial.TimerInterceptorAction">
<interceptor-ref name="timer"
/>这个表示应用拦截器
<result>/Timer.jspresult> 成功之后就跑到这个JSP页面了。
action>
package>
struts>
第三步:编写Timer.jsp页面
随便写点啥。
运行
可以在后台打印出来时间看到值!
上述例子演示了拦截器timer的用途——用于显示执行某个action方法的耗时,在我们做一个粗略的性能调试时,这相当有用。
想要检查一下某个Action的耗时情况就可以使用它进行操作了!
自定义拦截器
大家在开始着手创建自定义拦截器前,切记以下原则:
拦截器必须是无状态的,不要使用在API提供的ActionInvocation之外的任何东西。
要求拦截器是无状态的原因是Struts 2不能保证为每一个请求或者action创建一个实例,所以如果拦截器带有状态,会引发并发问题。
所有的Struts 2的拦截器都直接或间接实现接口com.opensymphony.xwork2.interceptor.Interceptor。除此之外,大家可能更喜欢继承类com.opensymphony.xwork2.interceptor.AbstractInterceptor。
以下例子演示通过继承AbstractInterceptor,实现授权拦截器。
示例:一个封装session操作的。框架是什么:框架其实就是把我们常用的东西打包
首先,创建授权拦截器类tutorial.AuthorizationInterceptor
package tutorial;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import java.util.Map;
import javax.annotation.security.RolesAllowed;
public class AuthorizationInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation ai) throws Exception {
Map session = (Map) 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 String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
@Override
public String execute() {
return SUCCESS;
}
}
以下是ShowUser.jsp的代码:
<body>
This is my JSP page. your role is <s:property value="role" /><br>
body>
然后,创建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:bean name="tutorial.Roles" id="roles" />
<s:form action="Login">
<s:radio list="#roles.roles" value="EMPOLYEE" name="role"
label="Role">s:radio>
<s:submit>s:submit>
s:form>
创建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;
}
}
最后配置文件
xml version="1.0" encoding="UTF-8"?>
DOCTYPE struts PUBLIC
"-//Apache
Software Foundation//DTD Struts Configuration 2.0//EN"
"">
<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"
>
/ShowUser.jsp result >
action >
package>
struts>
拦截器是Struts 2比较重要的一个功能。通过正确地使用拦截器,我们可以编写高可复用的代码。
我的几点认识
1、 配置里面的
<action name ="Timer" class ="tutorial.TimerInterceptorAction"
>
<interceptor-ref name ="timer"
/>
<result> /Timer.jsp result>
action >
注意里面的拦截器的名称timer必须要与Action同名的。要不然就找不到拦截器了!因为拦截器是与Action捆绑在一块的!