JavaShuo
欄目
標籤
Struts 2的基石——攔截器(Interceptor)
時間 2019-11-24
標籤
struts
基石
攔截
interceptor
欄目
Struts
简体版
原文
原文鏈接
首先,要跟你們道個歉,前一陣子爲給客戶個一個DEMO,忙得不可開交,因此好久沒有更新Blog。提到這個DEMO我想順便跟你們分享一下心得——若是你們但願快速開發,一個相似Struts 2這樣的簡單方便的WEB框架必不可少。咱們在開發DEMO使用的仍是Struts 1.2.8,並且沒有不使用任何EL(表達式語言),致使頁面出現無數相似「<%= ((Integer) request.getAttribute("xx")).intValue()%6 %>」的代碼。Struts 1.x的Form Bean的麻煩使得有部分同事直接使用request.getParameter(String arg),繼而引入另外一種麻煩。諸如此類的問題,在DEMO這樣時間緊迫的項目凸顯了Struts 1.x對快速開發的無能爲力。不過沒辦法,因爲咱們項目中的幾個資深員工除了Struts 1.x外,對其它的WEB框架彷佛不大感興趣。
言歸正傳,Interceptor(如下譯爲攔截器)是Struts 2的一個強有力的工具,有許多功能(feature)都是構建於它之上,如
國際化
、
轉換器
,
校驗
等。
什麼是攔截器
攔截器,在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 攔截器調用序列圖
已有的攔截器
Struts 2已經爲您提供豐富多樣的,功能齊全的攔截器實現。你們能夠到struts2-all-2.0.1.jar或struts2-core-2.0.1.jar包的struts-default.xml查看關於默認的攔截器與攔截器鏈的配置。
在本文使用是Struts 2的最新發布版本2.0.1。須要下載的朋友請點擊如下連接:
[url]http://apache.justdn.org/struts/binaries/struts-2.0.1-all.zip[/url]
如下部分就是從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能夠隨意寫些什麼到裏面。發佈運行應用程序,在瀏覽器的地址欄鍵入
[url]http://localhost:8080/Struts2_Interceptor/Timer.action[/url]
,在出現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
>
發佈運行應用程序,在瀏覽器地址欄中輸入:
[url]http://localhost:8080/Struts2_Interceptor/AuthorizatedAccess.action[/url]
。因爲此時,session尚未鍵爲「ROLE」的值,因此返回Login.jsp頁面,如圖2所示:
圖2 Login.jsp
選中Employee,點擊Submit,出現圖3所示頁面:
圖3 ShowRole.jsp
總結
攔截器是Struts 2比較重要的一個功能。經過正確地使用攔截器,咱們能夠編寫高可複用的代碼。
相關文章
1.
Struts 2的基石——攔截器(Interceptor)
2.
Struts 2的基石——攔截器(Interceptor)
3.
Interceptor攔截器
4.
Struts2的基石--攔截器
5.
Struts2攔截器(Interceptor)
6.
interceptor攔截器
7.
基於Struts 2 攔截器實現
8.
Struts 攔截器 、
9.
struts——攔截器
10.
Struts 攔截器
更多相關文章...
•
Mybatis實現映射器的2種方式
-
MyBatis教程
•
QBC的2種檢索方式
-
Hibernate教程
•
☆基於Java Instrument的Agent實現
•
Docker容器實戰(七) - 容器眼光下的文件系統
相關標籤/搜索
sql攔截器
攔截器
validation攔截器
攔截
Restful和攔截器
登錄攔截器
interceptor
基石
過濾器與攔截器的區別
Struts
瀏覽器信息
Docker教程
Docker命令大全
服務器
0
分享到微博
分享到微信
分享到QQ
每日一句
每一个你不满意的现在,都有一个你没有努力的曾经。
最新文章
1.
說說Python中的垃圾回收機制?
2.
螞蟻金服面試分享,阿里的offer真的不難,3位朋友全部offer
3.
Spring Boot (三十一)——自定義歡迎頁及favicon
4.
Spring Boot核心架構
5.
IDEA創建maven web工程
6.
在IDEA中利用maven創建java項目和web項目
7.
myeclipse新導入項目基本配置
8.
zkdash的安裝和配置
9.
什麼情況下會導致Python內存溢出?要如何處理?
10.
CentoOS7下vim輸入中文
本站公眾號
歡迎關注本站公眾號,獲取更多信息
相關文章
1.
Struts 2的基石——攔截器(Interceptor)
2.
Struts 2的基石——攔截器(Interceptor)
3.
Interceptor攔截器
4.
Struts2的基石--攔截器
5.
Struts2攔截器(Interceptor)
6.
interceptor攔截器
7.
基於Struts 2 攔截器實現
8.
Struts 攔截器 、
9.
struts——攔截器
10.
Struts 攔截器
>>更多相關文章<<