最近發現很多朋友連攔截器都不知道,于是想寫個BLOG總結一下。
java攔截器的基本原理其實非常簡單,說白了就是動態代理類。
下面來看一個簡單的例子
首先,我建立一個攔截器的類InterceptorClass,這里的before()和after()方法是以后攔截器會執行的方法
CODE清單一:
//攔截器
public class InterceptorClass {
public void before() {
System.out.println("攔截器InterceptorClass方法調用:before()!");
}
public void after() {
System.out.println("攔截器InterceptorClass方法調用:after()!");
}
}
??
?
我們模擬一個業務組件接口BusinessInterface,和一個業務組件實現類BusinessClass
CODE清單二:
/**
* Created by IntelliJ IDEA.
* User: Ming
* Date: 2010-9-7
* Time: 8:45:26
*/
//業務組件接口
public interface BusinessInterface {
public void doSomething();
}
????
?
?
CODE清單三:
/**
* Created by IntelliJ IDEA.
* User: Ming
* Date: 2010-9-7
* Time: 8:46:27
*/
//業務組件實現類
public class BusinessClass implements BusinessInterface {
public void doSomething() {
System.out.println("業務組件BusinessClass方法調用:doSomething()");
}
}
?
?
然后,創建一個動態代理類DynamicProxyHandler,這個類是集成InvocationHandler接口的,動態類的原理實際上是使得當你執行一個動態方
法的時候,他可以把這個動態方法dispatch到這個動態類上來。這樣,你就可以在這個方法的前后嵌入自己的一些方法。
CODE清單四:
/**
* Created by IntelliJ IDEA.
* User: Ming
* Date: 2010-9-7
* Time: 8:50:35
*/
/**
* 動態代理類,實現InvocationHandler接口.
* 包含了業務對象綁定動態代理類的處理
*/
public class DynamicProxyHandler implements InvocationHandler {
private Object business;//被代理對象
private InterceptorClass inceptor = new InterceptorClass();//攔截器
public DynamicProxyHandler(Object business) {
this.business = business;
}
???
?// 代理要調用的方法,并在方法調用前后調用連接器的方法
?
?
/**
* @param proxy 代理類對象
* @param method 被代理的接口方法
* @param args 被代理接口方法的參數
* @return
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
inceptor.before();
result = method.invoke(business, args);
inceptor.after();
return result;
}
?
OK,我們來寫個類測試一下
CODE清單五:
public static void main(String[] args) {
//生成待測試的業務組件對象
BusinessInterface business = new BusinessClass();
//生成動態代理類實例
DynamicProxyHandler handler = new DynamicProxyHandler(business);
BusinessInterface businessProxy = (BusinessInterface) Proxy.newProxyInstance(
//被代理類的ClassLoader
business.getClass().getClassLoader(),
//要被代理的接口,本方法返回對象會自動聲稱實現了這些接口
business.getClass().getInterfaces(),
//代理處理器對象
handler);
//用動態代理類調用方法
businessProxy.doSomething();
}
?
來看看結果:
近期struts2很流行,而且攔截器是struts2里面一個比較好的功能,下面舉個例子說明一下攔截器在struts2中的用法。
struts2對攔截器實現做了一個封裝,使得我們在實現的時候比較簡單。
首先我們要建一個攔截器類
CODE清單六:
public class AuthorizationInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
Map session = invocation.getInvocationContext().getSession();
String userName = (String) session.get("userName");
if ( userName != null && userName.equals("test")) {
System.out.println("攔截器:合法用戶登錄---");
return invocation.invoke();
}
else
{
System.out.println("攔截器:用戶未登錄---");
return Action.LOGIN;
}
}
}
?
?
這個類是必須要繼承struts2包中提供的AbstractInterceptor類,這個類有一個抽象方法intercept,這個方法是必須要實現的。
那么經理在這個攔截器里面寫了一個簡單的實現,對url用戶合法性做了一個限制。
接下來比較關鍵的是過濾器在struts2中的配置,先看看代碼
CODE清單七:
?
<package name="system" extends="struts-default">
<interceptors>
<!-- 定義權限控制攔截器 -->
<interceptor name="authority"
class="com.sharesin.biz.common.intercepts.struts2.AuthorizationInterceptor"/>
<!-- 定義一個包含權限控制的攔截器棧 -->
<interceptor-stack name="mystack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="authority"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!--定義默認攔截器 -->
<default-interceptor-ref name="mystack" />
<!--定義全局處理結果 -->
<global-results>
<result name="login">index.jsp</result>
</global-results>
<action name="login_*" class="com.sharesin.biz.web.system.LoginAction" method="{1}">
<result name="success">system/homepage.jsp</result>
</action>
</package>
??
在interceptors節點里,我們可以定義多個攔截器,這里的名為authority的只是其中的一個。struts2的攔截器棧我是先執行struts2默認的攔
截器defaultStack,然后再執行我的。然后只需要用default-interceptor-ref標簽設置好這個system包中的默認攔截器為這個攔截器就OK了。
struts2中引入了package這個概念,我覺得十分實用,當然這對struts2攔截器也是個實惠,我們可以根據不同的action來分包和不同的攔截器
ok,來運行測試一下。
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
