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.
安裝cuda+cuDNN
2.
GitHub的使用說明
3.
phpDocumentor使用教程【安裝PHPDocumentor】
4.
yarn run build報錯Component is not found in path 「npm/taro-ui/dist/weapp/components/rate/index「
5.
精講Haproxy搭建Web集羣
6.
安全測試基礎之MySQL
7.
C/C++編程筆記:C語言中的複雜聲明分析,用實例帶你完全讀懂
8.
Python3教程(1)----搭建Python環境
9.
李宏毅機器學習課程筆記2:Classification、Logistic Regression、Brief Introduction of Deep Learning
10.
阿里雲ECS配置速記
本站公眾號
歡迎關注本站公眾號,獲取更多信息
相關文章
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 攔截器
>>更多相關文章<<