最近发现很多朋友连拦截器都不知道于是想写个BLOG总结一下
java拦截器的基本原理其实非常简单说白了就是动态代理类
下面来看一个简单的例子
首先我建立一个拦截器的类InterceptorClass这里的before()和after()方法是以后拦截器会执行的方法
CODE清单一
Java代码
<SPAN >//拦截器
public class InterceptorClass {
public void before() {
Systemoutprintln(拦截器InterceptorClass方法调用:before()!);
}
public void after() {
Systemoutprintln(拦截器InterceptorClass方法调用:after()!);
}
}</SPAN>
我们模拟一个业务组件接口BusinessInterface和一个业务组件实现类BusinessClass
CODE清单二
Java代码
<SPAN >/**
* Created by IntelliJ IDEA
* User: Ming
* Date:
* Time: ::
*/
//业务组件接口
public interface BusinessInterface {
public void doSomething();
}</SPAN>
CODE清单三
Java代码
<SPAN >/**
* Created by IntelliJ IDEA
* User: Ming
* Date:
* Time: ::
*/
//业务组件实现类
public class BusinessClass implements BusinessInterface {
public void doSomething() {
Systemoutprintln(业务组件BusinessClass方法调用:doSomething());
}
}</SPAN>
然后创建一个动态代理类DynamicProxyHandler这个类是集成InvocationHandler接口的动态类的原理实际上是使得当你执行一个动态方
法的时候他可以把这个动态方法dispatch到这个动态类上来这样你就可以在这个方法的前后嵌入自己的一些方法
CODE清单四
Java代码
<SPAN >/**
* Created by IntelliJ IDEA
* User: Ming
* Date:
* Time: ::
*/
/**
* 动态代理类实现InvocationHandler接口
* 包含了业务对象绑定动态代理类的处理
*/
public class DynamicProxyHandler implements InvocationHandler {
private Object business;//被代理对象
private InterceptorClass inceptor = new InterceptorClass();//拦截器
public DynamicProxyHandler(Object business) {
thisbusiness = business;
}</SPAN>
// 代理要调用的方法并在方法调用前后调用连接器的方法
Java代码
<SPAN >/**
* @param proxy 代理类对象
* @param method 被代理的接口方法
* @param args 被代理接口方法的参数
* @return
* @throws Throwable
*/
public Object invoke(Object proxy Method method Object[] args) throws Throwable {
Object result = null;
inceptorbefore();
result = methodinvoke(business args);
inceptorafter();
return result;
}</SPAN>
OK我们来写个类测试一下
CODE清单五
Java代码
<SPAN > public static void main(String[] args) {
//生成待测试的业务组件对象
BusinessInterface business = new BusinessClass();
//生成动态代理类实例
DynamicProxyHandler handler = new DynamicProxyHandler(business);
BusinessInterface businessProxy = (BusinessInterface) ProxynewProxyInstance(
//被代理类的ClassLoader
businessgetClass()getClassLoader()
//要被代理的接口本方法返回对象会自动声称实现了这些接口
businessgetClass()getInterfaces()
//代理处理器对象
handler);
//用动态代理类调用方法
businessProxydoSomething();
}</SPAN>
来看看结果
近期struts很流行而且拦截器是struts里面一个比较好的功能下面举个例子说明一下拦截器在struts中的用法
struts对拦截器实现做了一个封装使得我们在实现的时候比较简单
首先我们要建一个拦截器类
CODE清单六
Java代码
<SPAN >public class AuthorizationInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
Map session = invocationgetInvocationContext()getSession();
String userName = (String) sessionget(userName);
if ( userName != null && userNameequals(test)) {
Systemoutprintln(拦截器合法用户登录);
return invocationinvoke();
}
else
{
Systemoutprintln(拦截器用户未登录);
return ActionLOGIN;
}
}
}
</SPAN>
这个类是必须要继承struts包中提供的AbstractInterceptor类这个类有一个抽象方法intercept这个方法是必须要实现的
那么经理在这个拦截器里面写了一个简单的实现对url用户合法性做了一个限制
接下来比较关键的是过滤器在struts中的配置先看看代码
CODE清单七
Java代码
<SPAN ><package name=system extends=strutsdefault>
<interceptors>
<! 定义权限控制拦截器 >
<interceptor name=authority
class=moninterceptsstrutsAuthorizationInterceptor/>
<! 定义一个包含权限控制的拦截器栈 >
<interceptorstack name=mystack>
<interceptorref name=defaultStack></interceptorref>
<interceptorref name=authority></interceptorref>
</interceptorstack>
</interceptors>
<!定义默认拦截器 >
<defaultinterceptorref name=mystack />
<!定义全局处理结果 >
<globalresults>
<result name=login>indexjsp</result>
</globalresults>
<action name=login_* class=websystemLoginAction method={}>
<result name=success>system/homepagejsp</result>
</action>
</package></SPAN>
在interceptors节点里我们可以定义多个拦截器这里的名为authority的只是其中的一个struts的拦截器栈我是先执行struts默认的拦
截器defaultStack然后再执行我的然后只需要用defaultinterceptorref标签设置好这个system包中的默认拦截器为这个拦截器就OK了
struts中引入了package这个概念我觉得十分实用当然这对struts拦截器也是个实惠我们可以根据不同的action来分包和不同的拦截器
ok来运行测试一下