Struts2 (四) — 攔截器
一、攔截器
1.概述
1.1什麽是攔截器
? 在struts2中,攔截器(Interceptor)是用來動態攔截Action執行的對象。
? 攔截器有點類似以前Servlet階段的Filter(過濾器) , 能夠在請求到達Action之前進行攔截操作, 可以在裏面進行判斷校驗。 典型的例子: 登錄攔截.
註:過濾器可以過濾servlet,jsp,html , 但攔截器只能攔截Action
1.2 struts2執行流程
? 客戶端請求Action,執行前端控制器,在前端控制器內部創建了Action的代理類,調用代理類的execute方法,在execute方法內部執行ActionInvocation的invoke方法。在invoke方法內部遞歸調用攔截器的攔截的方法。如果沒有下一個攔截器執行目標Action,Action執行結束後根據Result進行頁面跳轉,執行攔截器的後面相應的代碼,最後由response對象生成響應。
-
流程圖
-
時序圖
?
2.自定義攔截器
2.1方式一:實現Interceptor接口
? 最原始的方式,也是最基本的方式. 要實現三個方法,其中init 和 destroy ,平常我們都不太用。
-
創建一個類實現Interceptor接口
1 public class Interceptor01 implements Interceptor { 2 @Override 3 public String intercept(ActionInvocation invocation) throws Exception { 4 System.out.println("Interceptor01 執行了...");
-
在struts.xml裏面聲明攔截器
<package name="test" extends="struts-default" namespace="/"> <!-- 聲明攔截器
-
在action裏面使用攔截器
1 <action name="demo_*" class="com.pri.web.action.ActionDemo" method="{1}"> 2 <interceptor-ref name="interceptor01"></interceptor-ref> 3 </action>
2.2方式二:繼承AbstractInterceptor
? 是Interceptor的一個子類, 只需要重寫intercept()方法.
-
創建一個類繼承AbstractInterceptor
1 public class Interceptor02 extends AbstractInterceptor { 2 @Override 3 public String intercept(ActionInvocation invocation) throws Exception { 4 System.out.println("Interceptor01 執行了..."); 5 //放行 6 invocation.invoke(); 7 return null; 8 } 9 }
-
在struts.xml裏面聲明攔截器
1 <package name="test" extends="struts-default" namespace="/"> 2 <!-- 聲明攔截器 --> 3 <interceptors> 4 <interceptor name="interceptor02" class="com.pri.web.interceptor.Interceptor02"> </interceptor> 5 </interceptors> 6 </package>
-
在action裏面使用攔截器
1 <action name="demo_*" class="com.pri.web.action.ActionDemo" method="{1}"> 2 <interceptor-ref name="interceptor02"></interceptor-ref> 3 </action>
2.3方式三:繼承MethodFilterInterceptor【重點】
? 是AbstractInterceptor的一個子類.可以精確的控制攔截或者不攔截哪一個方法
-
創建一個類繼承MethodFilterInterceptor
1 public class Interceptor03 extends MethodFilterInterceptor { 2 @Override 3 protected String doIntercept(ActionInvocation invocation) throws Exception { 4 System.out.println("Interceptor03 執行了..."); 5 //放行 6 invocation.invoke(); 7 return null; 8 } 9 10 }
-
在struts.xml裏面聲明攔截器
1 <package name="test" extends="struts-default" namespace="/"> 2 <!-- 聲明攔截器 --> 3 <interceptors> 4 <interceptor name="interceptor03" class="com.pri.web.interceptor.Interceptor03"> </interceptor> 5 </interceptors> 6 </package>
-
在action裏面使用攔截器
1 <action name="demo_*" class="com.pri.web.action.ActionDemo" method="{1}"> 2 <interceptor-ref name="interceptor03"> 3 <!--不攔截fun02()方法 --> 4 <param name="excludeMethods">fun02</param> 5 </interceptor-ref> 6 </action>
註: 攔截器的執行順序,取決於action標簽中interceptor-ref的順序.
3.自定義攔截器相關的操作
3.1 攔截器不放行
? 攔截器的處理結果,莫過於兩種:
? 放行: 如果後面還有攔截器就執行下一個攔截器,如果後面沒有了攔截器,就執行action
? 攔截: 但是註意,攔截後也需要返回到一個具體的頁面。 所以需要配置result標簽
-
放行, 調用invoke()方法即可
-
攔截,跳轉其它頁面, 不調用invoke()方法
3.2自定義攔截器的問題【重視】
? 一旦自定義了自己的攔截器,那麽struts默認的哪一套 攔截器就不會走。 有點像有參構造和無參構造的關系。
-
struts默認的攔截器都有哪些呢?在struts-default.xml裏面有一個package 名字也叫作 struts-default 在這個包中定義了一個攔截器棧,名字叫做 defaultStack.
1 <interceptor-stack name="defaultStack"> 2 <interceptor-ref name="exception"/> 3 <interceptor-ref name="alias"/> 4 <interceptor-ref name="servletConfig"/> 5 <interceptor-ref name="i18n"/> 6 <interceptor-ref name="prepare"/> 7 <interceptor-ref name="chain"/> 8 <interceptor-ref name="scopedModelDriven"/> 9 <interceptor-ref name="modelDriven"/> 10 <interceptor-ref name="fileUpload"/> 11 <interceptor-ref name="checkbox"/> 12 <interceptor-ref name="datetime"/> 13 <interceptor-ref name="multiselect"/> 14 <interceptor-ref name="staticParams"/> 15 <interceptor-ref name="actionMappingParams"/> 16 <interceptor-ref name="params"/> 17 <interceptor-ref name="conversionError"/> 18 <interceptor-ref name="validation"> 19 <param name="excludeMethods">input,back,cancel,browse</param> 20 </interceptor-ref> 21 <interceptor-ref name="workflow"> 22 <param name="excludeMethods">input,back,cancel,browse</param> 23 </interceptor-ref> 24 <interceptor-ref name="debugging"/> 25 <interceptor-ref name="deprecation"/> 26 </interceptor-stack> 27 .... 28 <default-interceptor-ref name="defaultStack"/>
-
如果我們給自己的action使用了自己定義的攔截器,那麽上面默認的這些攔截器都不會生效了,失去了這些功能,如果還想使用默認的這些攔截器。那麽可以在action裏面再引用它即可。
1 <action name="actionDemo_*" class="com.itheima.action.ActionDemo" method="{1}"> 2 <!-- 執行這個action,就必然要走名字叫做myInterceptor02的攔截器 --> 3 <!-- 使用默認的攔截器 --> 4 <interceptor-ref name="defaultStack"></interceptor-ref> 5 6 <!-- 使用自定義的攔截器 --> 7 <interceptor-ref name="myInterceptor"></interceptor-ref> 8 <result name="login">/index.jsp</result> 9 </action>
二、標簽庫
1.概述
1.1 Struts2標簽庫介紹
Struts2標簽庫是一個比較完善,且功能強大的標簽庫,它將所有標簽都統一到一個標簽庫中,從而簡化了標簽的使用,它還提供主題和模板的支持,極大地簡化了視圖頁面代碼的編寫。
1.2 Struts2標簽庫分類
這些標簽都在 docs/docs/tag-reference.html
裏面可以找到
1.3使用步驟
-
如果使用Struts2的標簽庫,必須導入庫到頁面
<%@ taglib uri="/struts-tags" prefix="s" %>
-
根據語法書寫標簽庫...
2.流程控制標簽庫
-
if標簽
,elseif標簽
...類似JSP裏面的c:if取值: <s:property value="#request.a"/><br/> ? <s:if test="#request.a > 10"> a 大於10 </s:if> <s:else> a 小於或者等於10 </s:else>
-
iterator標簽
類似JSP裏面的c:foreach<s:iterator value="list" var="u"> <s:property value="username"/> <s:property value="password"/> </s:iterator>
3.UI標簽
3.1 表單標簽
-
和HTML標簽對比
<h1>一,HTML的表單標簽</h1> <form action="${pageContext.request.contextPath }/demo03_fun03" method="post"> 用戶名:<input type="text" name="username"/><br/> 密碼: <input type="password" name="password"/><br/> 性別:<input type="radio" name="sex" value="1"/>男<input type="radio" name="sex" value="0"/>女<br/> 愛好: <input type="checkbox" name="hobby" value="lq"/>籃球 <input type="checkbox" name="hobby" value="zq"/>足球 <input type="checkbox" name="hobby" value="ppq"/>乒乓球 <input type="checkbox" name="hobby" value="qdm"/>敲代碼<br/> 籍貫:<select name="address"> <option value="-1">-請選擇-</option> <option value="0">北京</option> <option value="1">上海</option> <option value="2">深圳</option> </select><br/> 自我介紹:<textarea rows="2" cols="8" name="introduce">哈哈哈</textarea><br/> <input type="submit" /> </form> ? <h1>二,Struts2的表單標簽</h1> <!--默認請求方式就是post,action不用寫項目路徑 --> <s:form action="/demo03_fun03"> <s:textfield name="username" label="用戶名" /> <s:password name="password" label="密碼"/> <%-- <s:radio list="{‘男‘,‘女‘}" name="sex" label="性別"/> --%> <s:radio list="#{‘1‘:‘男‘,‘0‘:‘女‘ }" name="sex" label="性別" value="1"></s:radio> <s:checkboxlist list="{‘籃球‘,‘足球‘,‘乒乓球‘,‘敲代碼‘}" label="愛好" name="hobby"/> <s:select list="#{‘0‘:‘北京‘,‘1‘:‘上海‘,‘2‘:‘深圳‘ }" label="籍貫" name="address" headerKey="-1" headerValue="請選擇" value="1"></s:select> <s:textarea cols="8" rows="2" name="introduce" label="籍貫" value="哈哈"></s:textarea> <s:submit value="註冊" align="left"/> </s:form>
Struct2標簽特點:
? 自動加了樣式, 標簽都套了一層表格.對齊了
? 有自動回顯數據的功能.
3.2Struts2模版和主題
? 主題就是一種風格化標簽,能夠讓所有UI標簽能夠產生同樣的視覺效果而歸集到一起的一組模板,即風格相近的模板被打包為一個主題. struts2提供了四種主題simple、xhtml、css_xhtml、ajax。
? simple:把UI標簽翻譯成最簡單的HTML對應元素,而且會忽視行標屬性
? xhtml:默認的主題。這個主題的模板通過使用一個布局表格提供了一種自動化的排版機制(默認)
? css_xhtml:這個主題裏的模板與xhtml主題裏的模板很相似,但他們將使用css來進行布局和排版
? ajax:這個主題裏的模板以xhtml主題裏的模板為基礎,但增加了一些ajax功能。
-
通過配置struts.xml文件中的常量屬性struts.ui.theme修改主題風格. 全局的
<constant name="struts.ui.theme" value="simple"></constant>
-
也可以通過UI標簽的theme屬性進行修改
<s:form action="..." theme="simple">
二、struts2註解開發
1.開發流程
-
導入struts的環境jar,導入註解額外的jar
struts2-convention-plugin-x.x.x.jar
-
在action類中配置註解標簽
2.註解
-
struts2.xml
<package name="test" extends="struts-default" namespace="/"> <action name="demo_fun01" class="com.pri.web.action.ActionDemo01" method="fun01"> <result name="success">/demo01.jsp</result> </action> </package>
-
Namespace 註解
? 用來模擬package標簽的
namespace屬性
的。? 需要在Action的類上配置。
-
ParentPackage 註解
? 用來模擬package標簽的
extends屬性
的。? 需要在Action的類上配置。
-
Action註解
? 用來模擬
action標簽
的。需要在action類中的action方法上配置。? value屬性用來模擬
action標簽
中的name屬性
? results屬性用來模擬
action標簽
內的result標簽
-
Result註解
? 用來模擬result標簽的。可以在action類上配置或者在action方法上配置。? action類上配置就是全局的。action方法上的配置是局部的。
? name屬性用來模擬
result標簽
的name屬性
? type屬性用來模擬
result標簽
的type屬性
? locaction屬性用來模擬
result標簽
的標簽內容? params屬性用來模擬
result標簽
的內部
Struts2 (四) — 攔截器