亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Struts 2的基石——攔截器(Interceptor)

系統 1631 0

什么是攔截器

攔截器,在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 攔截器調用序列圖
圖1 攔截器調用序列圖

已有的攔截器

Struts 2已經為您提供豐富多樣的,功能齊全的攔截器實現。大家可以到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" />
< 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可以隨意寫些什么到里面。發布運行應用程序,在瀏覽器的地址欄鍵入 http://localhost:8080/Struts2_Interceptor/Timer.action ,在出現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 >

發布運行應用程序,在瀏覽器地址欄中輸入: http://localhost:8080/Struts2_Interceptor/AuthorizatedAccess.action 。由于此時,session還沒有鍵為“ROLE”的值,所以返回Login.jsp頁面,如圖2所示:

圖2 Login.jsp
圖2 Login.jsp

選中Employee,點擊Submit,出現圖3所示頁面:

圖3 ShowRole.jsp
圖3 ShowRole.jsp

總結

攔截器是Struts 2比較重要的一個功能。通過正確地使用攔截器,我們可以編寫高可復用的代碼。

Struts 2的基石——攔截器(Interceptor)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国内精品久久久久久久星辰影视 | 午夜色大片在线观看 | 亚洲伦理一二三四 | 久久美| 午夜亚洲 | 大片毛片女女女女女女女 | 亚洲精品一区二区三区四区手机版 | 日韩1| 中文字幕中文字幕中中文 | 俄罗斯三级毛片 | 女人18毛片a级18毛多水真多 | 在线中文字幕网 | 国产亚洲综合一区二区在线 | 国产精品久久久久久久久福利 | 七七久久综合 | 色综合久久天天综合绕观看 | 香蕉网站男人网站 | 国产成人在线免费 | 亚洲精品成人久久 | 四虎影视在线观看 | 免费一级欧美大片久久网 | 欧美一级毛片免费观看 | 国产精品国内免费一区二区三区 | 国产成人啪一区二区 | 久久不见久久见免费影院 | 久久手机免费视频 | 999久久免费高清热精品 | 精品偷拍模特露出丝袜在线 | 亚洲欧美日产综合一区二区三区 | 国产激情久久久久影院小草 | 朴妮唛禁福利视频在线 | 黄色毛片视频 | 中文福利视频 | 美女一级免费毛片 | 久久网在线 | 久久精品国产亚洲精品 | 免费看成人播放毛片 | 久久青草免费视频 | 免费精品国产自产拍观看 | 日韩在线第二页 | 亚洲日韩中文字幕在线播放 |