加載流程
StrutsPrepareAndExecuteFilter Struts2中的核心類,有兩個功能:預(yù)處理與執(zhí)行
-
預(yù)處理
-
配置文件加載順序
struts.properties ---- 配置常量
name = value
-
struts.xml ---- 配置Action及常量
<constant name="" value="">
使用
include
進行分模塊開發(fā),在struts.xml中包含其他配置文件,被包含的文件都是標(biāo)準(zhǔn)的struts配置文件<include file="struts.xml"/> <include file="com/sd/struts.xml"/>
-
web.xml ---- 配置核心過濾器及常量
init-param
以上三個配置文件均可添加常量桩撮,后加載的配置文件中的常量值會將先加載配置文件中的常量值覆蓋
-
配置常量
-
國際化,解決post提交亂碼
<constant name="struts.i18n.encoding
-
指定訪問action的后綴名邀窃,以下指定后綴為action或不進行配置
<constant name="struts.action.extension" value="action,,"/>
-
指定struts2是否以開發(fā)模式運行
- 熱加載主配置
- 提供更多的錯誤信息輸出,方便開發(fā)時調(diào)試
<constant name="struts.devMode" value="true"/>
默認配置
<struts>
<package name="demo" extends="struts-default" namespace="/">
<!-- 如果訪問路徑404時嘱能,跳轉(zhuǎn)到default-action-ref指定action -->
<default-action-ref name="demo1"/>
<!-- method 默認為execute()-->
<!-- result name 默認為success-->
<!-- result type 默認為dispatcher-->
<!-- class 默認為com.opensymphony.xwork2.ActionSupport -->
<action name="demo1">
<result name="*" type="dispatcher">/welcome.jsp</result>
</action>
</package>
</struts>
Action編寫方式
-
普通POJO類
定義業(yè)務(wù)方法撬呢,默認為execute()方法
public String execute()
伦吠,也可實現(xiàn)其他方法(需要在struts.xml中定義,method
參數(shù)執(zhí)行定義的方法) -
實現(xiàn)Action接口,定義了五個字符串常量
SUCCESS,NONE,ERROR,INPUT,LOGIN
-
繼承ActionSupport類
提供了許多默認方法魂拦,包括獲取國際化信息的方法讨勤,數(shù)據(jù)校驗方法,默認的用戶請求方法等
Action動態(tài)方法調(diào)用
-
通配符配置
- 配置struts.xml
<struts> <package name="demo" extends="struts-default" namespace="/"> <global-allowed-methods>regex:.*</global-allowed-methods> <action name="demo1_*" class="com.sd.action.Action1" method="{1}"> <result name="*">/welcome.jsp</result> </action> </package> </struts>
name屬性中的*代表任意字符晨另,method中的{1}代表name屬性中出現(xiàn)的第一個 * 所代替的字符
-
定義
public String add() { System.out.println("增加"); return SUCCESS; }
-
引用
<h4><a href="${pageContext.request.contextPath}/demo1_add">示例一:增加</a></h4>
-
-
動態(tài)訪問(使用!來匹配方法,不符合SEO引擎優(yōu)化)
-
開啟動態(tài)訪問struts.xml
<struts> <constant name="struts.enable.DynamicMethodInvocation" value="true"/> <package name="demo" extends="struts-default" namespace="/"> <global-allowed-methods>regex:.*</global-allowed-methods> <action name="demo1" class="com.sd.action.Action1"> <result name="*">/welcome.jsp</result> </action> </package> </struts>
-
-
定義
public String add() { System.out.println("增加"); return SUCCESS; }
-
引用
<h4><a href="${pageContext.request.contextPath}/demo1!add">示例一:增加</a></h4>
Structs2訪問servlet API
-
ActionContext
-
HttpServletRequest(獲取,設(shè)置request參數(shù))
void put(String key,Object value)
Object get(String key)
HttpParameters getParameters()
-
Application
void setApplication(Map<String,Object> application)
Map<String,Object> getApplication()
-
Session
void setSession(Map<String,Object> session)
Map<String,Object> getSession()
-
ActionContext
static ActionContext getContext();
//獲取當(dāng)前線程的ActionContext 對象
-
ServeletActionContext
-
通過特定接口訪問
- ServletRequestAware:實現(xiàn)該接口的Action可以直接訪問web應(yīng)用的HttpServletRequest實例
- ServletResponseAware:實現(xiàn)該接口Action可以直接訪問web應(yīng)用的HttpServletResponse實例
- SessionAware:實現(xiàn)該接口Action可以直接訪問web應(yīng)用的HttpSession實例
- SevletContextAware:實現(xiàn)該接口Action可以直接訪問web應(yīng)用的SevletContext實例
結(jié)果頁面配置
- 跳轉(zhuǎn)方式
//轉(zhuǎn)發(fā)到Action
<result name="*" type="chain">
<param name="actionName">demo1</param>
<param name="namespace">/</param>
</result>
//轉(zhuǎn)發(fā)到JSP
<result name="*" type="dispatcher">/welcome.jsp</result>
//重定向到JSP
<result name="*" type="redirect">/welcome.jsp</result>
//重定向到Action
<result name="*" type="redirect">
<param name="actionName">demo1</param>
<param name="namespace">/</param>
</result>
-
全局結(jié)果頁面配置
在這個包下所有返回相同字符串的值谱姓,都可以向這個頁面進行跳轉(zhuǎn)
<global-results> <result name="error">/welcome.jsp</result> </global-results>
-
局部頁面配置
某個Action中返回的字符串的值借尿,會向這個頁面跳轉(zhuǎn)
<action name="demo1"> <result name="*" type="dispatcher">/welcome.jsp</result> </action>
獲得參數(shù)的方式
-
屬性驅(qū)動
- 準(zhǔn)備與參數(shù)鍵名稱相同的屬性
- 自動類型轉(zhuǎn)換,只能轉(zhuǎn)換8大基本數(shù)據(jù)類型及對應(yīng)包裝類
- 支持特定類型字符串轉(zhuǎn)化為Date,例如yyyy-MM-dd
對象驅(qū)動
-
模型驅(qū)動(實現(xiàn)ModelDriven接口)
//此處必須手動new 對象屉来,否則會報NPE private User userhaha=new User(); @Override public User getModel() { return userhaha; }
-
集合類型參數(shù)封裝
-
List
-
定義
private List<User> userList; public List<User> getUserList() { return userList; } public void setUserList(List<User> userList) { this.userList = userList; }
-
jsp配置
<form action="${pageContext.request.contextPath}/parm" method="post"> 姓名:<input type="text" name="userList.name"></br> 年齡:<input type="text" name="userList.age"></br>//userList默認為userList[0] 生日:<input type="text" name="userList[0].birthday"> </br> </br> </br> 姓名:<input type="text" name="userList[1].name"></br> 年齡:<input type="text" name="userList[1].age"></br> 生日:<input type="text" name="userList[1].birthday"> <input type="submit" value="提交"> </form>
-
-
Map
-
定義
private Map<String,User> users; public Map<String, User> getUsers() { return users; } public void setUsers(Map<String, User> users) { this.users = users; }
-
配置
<form action="${pageContext.request.contextPath}/param" method="post"> 姓名:<input type="text" name="users['one'].name"><br> 年齡:<input type="text" name="users['one'].age"><br> 生日:<input type="text" name="users['one'].birthday"><br> 愛好: 跑步:<input type="checkbox" name="users['one'].love" value="run"><br> 讀書:<input type="checkbox" name="users['one'].love" value="book"><br> 寵物:<input type="checkbox" name="users['one'].love" value="pat"><br> 聯(lián)系人1:<br> 姓名:<input type="text" name="users['two'].name"><br> 年齡:<input type="text" name="users['two'].age"><br> 生日:<input type="text" name="users['two'].birthday"><br> <%-- 聯(lián)系人2:<br> 姓名:<input type="text" name="users['two'].name"><br> 年齡:<input type="text" name="users['two'].age"><br> 生日:<input type="text" name="users['two'].birthday"><br>--%> <input type="submit" value="提交"><br> </form> //備注:同一個name值不能出現(xiàn)兩次及兩次以上
-
-
聲明式異常處理
根據(jù)<exception-mapping>
出現(xiàn)的位置,異常映射分為兩種:
- 局部異常映射:將
<excepion-mapping>
元素作為<action>
元素的子元素配置; - 全局異常映射:將
<exception-mapping>
元素作為<global-exception-mappings>
元素的子元素
<package name="demo" namespace="/" extends="struts-default">
<global-results>
<result name="sql">/index.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping result="sql" exception="java.sql.SQLException"/>
</global-exception-mappings>
<action name="testParams" class="com.ognl.Demo1Action">
<exception-mapping result="sql" exception="java.sql.SQLException"/>
</action>
</package>
全局異常映射對所有的 Action 類都有效,但局部異常映射僅對該異常映射所在的 Action 有效;
攔截器
-
生命周期
生命周期隨項目啟動創(chuàng)建路翻,隨項目關(guān)閉而銷毀
-
自定義攔截器
實現(xiàn)Interceptor接口
繼承AbstractInterceptor類
-
繼承MethodFilterInterceptor類(方法過濾攔截器)
定制攔截器攔截方法(攔截哪些方法,哪些方法不攔截)
@Override protected String doIntercept(ActionInvocation actionInvocation) throws Exception { /** * 攔截器放行茄靠,需要調(diào)用actionInvocation.invoke()方法,返回null即可茂契,邏輯視圖由Action處理 * 攔截器不放行,不需要調(diào)用actionInvocation.invoke()方法,需要返回一個字符串作為邏輯視圖慨绳, * 系統(tǒng)會根據(jù)返回的字符串跳轉(zhuǎn)到對應(yīng)的視圖資源 */ //前處理 actionInvocation.invoke();//放行 //后處理 return null;//返回邏輯視圖 }
-
配置攔截器
注冊攔截器
指定攔截器棧
-
指定默認攔截器棧掉冶,定制方法是否攔截
<interceptors> <!-- 注冊攔截器 --> <interceptor name="myInters" class="com.interceptor.MyInterceptor"/> <!-- 指定攔截器棧--> <interceptor-stack name="myStack"> <!-- 引用定義攔截器 --> <interceptor-ref name="myInters"> <!-- 不能同時指定 --> <!-- 指定方法不攔截 --> <param name="excludeMethods">add,select</param> <!-- 指定方法攔截 --> <!-- <param name="includeMethods"></param> --> </interceptor-ref> <!-- 引用默認攔截器 --> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors> <!-- 指定默認的攔截器棧 --> <default-interceptor-ref name="myStack"/>
OGNL與Struts2的體現(xiàn)(ValueStack)
? 默認情況下,棧(CompoundRoot root)中放置當(dāng)前訪問的Action對象,提供push()
和pop()
方法脐雪。Context部分就是ActionContext數(shù)據(jù)中心
-
參數(shù)接受
通過ognl來實現(xiàn)原生接受到的參數(shù)轉(zhuǎn)換成最終Action對象的參數(shù)獲取方法(以上三種)
//獲取值棧 ValueStack stack = ActionContext.getContext().getValueStack(); stack.push(xxx);
-
配置文件
<struts> <package name="demo" namespace="/" extends="struts-default"> <action name="testParams" class="com.ognl.Demo1Action"> <result name="success" type="redirectAction"> <param name="namespace">/</param> <param name="actionName">params</param> <!-- 如果添加的參數(shù) struts "看不懂"厌小,則就會作為參數(shù),附加到重定向的路徑之后战秋, 如果參數(shù)是動態(tài)的璧亚,可以使用${ }包裹ognl表達式動態(tài)取值,取值的位置位于ognl 的值棧區(qū)脂信,即對應(yīng)的Action對象--> <param name="name">${name}</param> </result> </action> <action name="params" class="com.ognl.Demo2Action"> <result name="*">/index.jsp</result> </action> </package> </struts>
public class Demo1Action extends ActionSupport{ private String name="李雷與韓梅梅"; @Override public String execute() throws Exception { return SUCCESS; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
http://localhost:8080/params.action?name=李雷與韓梅梅
-
Struts2標(biāo)簽
<%@ taglib prefix="s" uri="/struts-tags" %>
-
Debug
<s:debug/>
-
遍歷標(biāo)簽
!-- 遍歷標(biāo)簽 --> <s:iterator value="#names" status="st"> <s:if test="#st.odd"> <s:property value="#st.index"/><br/> </s:if> <s:property/><br/> </s:iterator> <s:iterator value="#names" var="name"> <s:property value="#name"/><br/> </s:iterator> <s:iterator begin="1" end="10" status="1"> <s:property/> </s:iterator> <br/> <s:if test="#names.size()==4"> list 長度為4 </s:if> <s:elseif test="#names.size()==5"> list 長度為5 </s:elseif> <s:else> list 長度不為4 </s:else>
-
屬性標(biāo)簽
根據(jù)是否帶#決定是在ValueStack哪個部分取值
<s:property value="hello"/><br/> <s:property value="hello.length()"/><br/> <s:debug/>
?
-