很久沒用struts2 一年多了吧。好多東西已經模糊忘記了。轉篇博客恢復下記憶吧! html
●開發準備
1.引入類庫 直接從struts/apps/struts2-blank/WEB-INF/lib下拷貝
除junit和spring-test以外的全部jar包
2.複製一個struts.xml
直接從struts/apps/struts2-blank/WEB-INF/classes下拷貝struts.xml
3.對web.xml配置 一樣從
struts/apps/struts2-blank/WEB-INF/web.xml中拷貝
<filter></filter>和<filter-mapping></filter-mapping>以及其中的所有內容
●Action
1.struts2的做用就是讓用戶請求和返回視圖(servlet api)分離。
2.namespace決定了action的訪問路徑,默認爲"",能夠接收全部路徑的action
namespace能夠寫爲/,或者/xxx,或者/xxx/yyy,對應的action訪問路徑爲/xxx.action
/xxx/xxx.action,或者/xxx/yyy/xxx.action
namespace最好也用模塊來進行命名 好比用戶模塊 就用user
3.具體視圖的返回能夠由用戶本身定義的Action來決定
具體的手段是根據返回的字符串找到對應的配置項,來決定視圖的內容
具體Action的實現能夠是一個普通的java類,裏面有public String execute方法便可
或者實現Action接口
不過最經常使用的是從ActionSupport繼承,好處在於能夠直接使用Struts2封裝好的方法
4.struts2中的路徑問題是根據action的路徑而不是jsp路徑來肯定,因此儘可能不要使用相對路徑。
雖然能夠用redirect方式解決,但redirect方式並不是必要。
解決辦法很是簡單,統一使用絕對路徑。(在jsp中用request.getContextRoot方式來拿到webapp的路徑)
或者使用myeclipse常常用的,指定basePath
5.Action執行的時候並不必定要執行execute方法
能夠在配置文件中配置Action的時候用method=來指定執行哪一個方法
也能夠在url地址中動態指定(動態方法調用DMI)(推薦)
前者會產生太多的action,因此不推薦使用
6.使用通配符,將配置量降到最低
不過,必定要遵照"約定優於配置"的原則,即命名規則統一。 java
- <action name="Student*" class="com.bjsxt.struts2.action.StudentAction" method="{1}">
- <result>/Student{1}_success.jsp</result>
*代替字符串,{1}表明第一個*所匹配的字符串。
- <action name="*_*" class="com.bjsxt.struts2.action.{1}Action" method="{2}">
- <result>/{1}_{2}_success.jsp</result>
7.使用action屬性接收參數,在URL地址中傳的參數和action裏的成員變量能夠是一一對應的,
action初始化時,會自動將成員變量的值初始化成參數的值。(struts調set方法,因此set方法名
和url參數的名必須匹配而真正的成員變量名不必定非要匹配)
8.使用Domainmodel(領域模型)接收參數 action類中能夠不寫具體的屬性而將其寫入領域模型中,
而後action類中持有一個領域模型的對象的引用,在url中一樣能夠傳參數直接對領域模型對象的屬性賦值,
寫法爲 namespace/actionname!method?domainmodel.parameter=XXX&domainmodel.parameter=XXX,
(也多是method?domainmodel.parameter.parameter.parameter=XXX,此時domainmodel成員變量爲另外一個對象,
另外一個對象的成員變量爲另另外一個對象)
當領域模型與實際參數的屬性不一樣時,如,password每每有確認password,則新建一個dataTransferObject類來接收參數並判斷,再初始化領域模型。此時action類中持有的則是DTO的引用。
9.咱們也可使action類實現ModelDriven<User>接口,使用接口中的getmodle方法來使action自動得到領域模型,這樣即便在action類中包含了領域模型的引用,一樣能夠在url中直接寫 namespace/actionname!method?parameter=XXX¶meter=XXX.使用這個方法時,在action中要本身new一個模型。
10.
- <constant name="struts.i18n.encoding" value="GBK" />
struts.xml解決中文問題的標籤,這些標籤能夠在struts2-core-2.1.6.jar中的org.apache.struts2中的default.properties中查詢默認值。
在2.1.6以前,中文問題是個BUG,在2.1.7中已修正。
11.使用struts的標籤來將程序中對用戶的提示信息打印到前臺頁面:
在後臺 使用
- this.addFieldError("name","name is error");
其中name爲action中的屬性,"name is error"爲錯誤信息的提示 web
- <s:fielderror fieldName="name" />
將帶有簡單格式的提示信息打印到前臺
首先,在前臺頁面中包含 spring
- <%@taglib uri="/struts-tags" prefix="s" %>
在META-INF下struts-tag.tld中有標籤詳細信息 頁面中使用<s:debug></s:debug>
能夠觀察ValueStack裏保存的action中的屬性。
屬性都是存在map中的,有值,有名,而 值,是個數組,
因此咱們用<s:property value="errors.name[0]">能夠取到錯誤信息的具體字符串。
12.
1、
後臺程序能夠經過ActionSupport中的方法
- request = (Map)ActionContext.getContext().get("request");
- session = ActionContext.getContext().getSession();
- application = ActionContext.getContext().getApplication();
獲得map類型的 request,session,application.
還能夠經過put方法對這些名值對進行賦值。
在前臺頁面,能夠經過
- <s:property value="#request.r1"/> | <%=request.getAttribute("r1") %> <br />
- <s:property value="#session.s1"/> | <%=session.getAttribute("s1") %> <br />
- <s:property value="#application.a1"/> | <%=application.getAttribute("a1") %> <br />
來拿到所設置的request、session、application.既用#key來訪問或者用最原始的jsp語言來訪問。
二(經常使用)、
一樣設置三個成員變量 但使用範型
- private Map<String, Object> request;
- private Map<String, Object> session;
- private Map<String, Object> application;
而後設置set方法,由struts將頁面元素對象自動設置進去(實現RequestAware,SessionAware,ApplicationAware),
而後調用put方法,往進寫東西。
3、
一樣設置三個成員變量 但類型不一樣
- private HttpServletRequest request;
- private HttpSession session;
- private ServletContext application;
而後初始化
- request = ServletActionContext.getRequest();
- session = request.getSession();
- application = session.getServletContext();
而後由request.setAttribute("r1", "r1")往進設置值。
4、
一樣設置三個成員變量
- private HttpServletRequest request;
- private HttpSession session;
- private ServletContext application;
- //初始化
- public void setServletRequest(HttpServletRequest request) {
- this.request = request;
- this.session = request.getSession();
- this.application = session.getServletContext();
- }
- //而後由request.setAttribute("r1", "r1")設值。
13.模塊包含
在struts.xml中能夠將其餘xml文檔包含
- <include file="XXXX.xml" />
這樣的好處是,多個模塊能夠同時開發,而後包含就能夠協做工做。
14.默認action
在url的namespace後什麼都不敲入或敲入不存在的action時,訪問默認的action
- <default-action-ref name="index"></default-action-ref>
而後再jsp中使用
接受參數。
●result
15.result的type(類型)屬性
·默認爲dispatcher 運用jsp跳轉(forward)到結果頁面 不能跳轉到action
·redirect 重定向到結果頁面 不能跳轉到action
·chain forward跳轉到一個action
·redirectAction 重定向到一個action
·freemarker
·httpheader 發一個http的頭信息
·stream 下載
·velocity
·xslt xml的修飾
·plaintext 頁面源碼
·tiles 頁面分塊後動態指定
假如chain forward跳轉的action在某包內
則 apache
- <result type="chain">
- <param name="actionName">adfadf</param>
- <param name="namespace">/XXXXXX</param>
- </reuslt>
在struts-2.2.1.1-docs/struts-2.2.1.1/docs/chain-result.html可查
16.global-results全局結果集在,同一個package中你們能夠共用的結果視圖
- <global-results>
- <result name="mainpage">/main.jsp</result>
- </global-results>
其餘package中也想使用此package的result,則extends="packagename"
- <package name="admin" namespace="/admin" extends="user">
則此包內擁有user包的action
17.動態結果集 即<result>${r}</result>,此時r爲action的成員變量 xml中${}能夠讀取valuestack裏的內容
r的值能夠動態指定爲一個字符串,例如"/user_success.jsp"。
18.帶參數的結果集。
因爲forward服務器內跳轉共享一個值棧,因此參數也共享,即沒有必要傳。
而再redirect客戶端重定向的時候,值棧不共享,是兩次request過程,
此時但願action向新定向到的頁面傳參數須要使用?paramname=${paramname}
即
- <result type="redirect">/user_success.jsp?t=${type}</result>
此時若是在user_success.jsp使用struts的<s:property value="t">
標籤取值取不出,由於不是action沒有值棧actionstack。
只能用<s:property value="#parameters.t">從actioncontext中取。
●ognl表達式
1.action中的成員變量爲domainmodel對象引用時,能夠在前臺傳參數來初始化這個對象,不傳不構造,
也能夠本身new。可是,若是要使用傳參來初始化的時候domainmodel必須有一個空的構造方法。。
2.
訪問值棧中的action的普通屬性 <s:property value="username"/> 直接寫屬性名
訪問值棧中對象的普通屬性<s:property value="cat.friend.name"/> 對象名.成員變量名(是對象).成員變量名
訪問值棧中對象的普通方法<s:property value="password.length()"/> 對象名.方法名()
訪問值棧中action的普通方法<s:property value="m()"/> 直接寫方法名()
3.
訪問靜態方法 <s:property value="@com.bjsxt.struts.ognl.S@s()"/> @類名@方法名()
在struts中要有一個設置<constant name="struts.ognl.allowStaticMethodAccess" value="true"><constant>
設置後才容許靜態方法訪問,這些在default.properties配置文件中能夠查到
訪問靜態屬性 <s:property value="@com.bjsxt.struts.ognl.S@STR"/> @類名@屬性名
訪問Math類的靜態方法:<s:property value="@@max(2,3)" /> @@方法名
4.
訪問普通類的構造方法:<s:property value="new com.bjsxt.struts2.ognl.User(8)"/> new 全類名(參數)
訪問List中某個元素:<s:property value="users[1]"/> List名[下標]
訪問List中元素某個屬性的集合:<s:property value="users.{age}"/> 把users中每一個user拿出來,
再把每一個user的age拿出來組成一個新的List。 list名.{屬性名}
訪問List中元素某個屬性的集合中的特定值:<s:property value="users.{age}[0]"/> 把users中每一個user拿出來,
再把每一個user的age拿出來組成一個新的List,取第0個。 list名.{屬性名}[下標]
訪問Set:<s:property value="dogs"/>
訪問Set中某個元素:<s:property value="dogs[1]"/> 因爲set是無序的因此取不到
訪問Map:<s:property value="dogMap"/>
訪問Map中某個元素:<s:property value="dogMap.dog101"/> map名.key名 或者dogMap['dog101']或者dogMap[/"dog101/"]
訪問Map中全部的key:<s:property value="dogMap.keys"/> 拿到了key的集合
訪問Map中全部的value:<s:property value="dogMap.values"/> 拿到了value的集合
訪問容器的大小:<s:property value="dogMap.size()"/> | <s:property value="users.size"/>不加()也能夠,
ognl認爲它是個屬性。
5.
投影(過濾):<s:property value="users.{?#this.age==1}[0]"/>
從users(list)中拿出age爲1的user並將其放入集合,取第0個。
投影:<s:property value="users.{^#this.age>1}.{age}"/>
從users中拿出age大於1的 取開頭那個 把年齡輸出
投影:<s:property value="users.{$#this.age>1}.{age}"/>
從users中拿出age大於1的 取結尾那個 把年齡輸出
投影:<s:property value="users.{$#this.age>1}.{age} == null"/>
從users中拿出age大於1的 取結尾那個的年齡 看是否爲空
6.
用[]訪問valuestack裏面的元素 action永遠在棧頂
[]:<s:property value="[0].username"/> 此時訪問的是從0位置開始也就是從action的位置
開始往下的元素直到棧底。若是用到服務器端跳轉,用到的action會挨個被壓入valuestack中。
●Struts標籤
首先,在前臺頁面中包含<%@taglib uri="/struts-tags" prefix="s" %>
1.property
- <s:property value="username"/>
將username屬性的值打印出來
- <s:property value="'username'"/>
將username字符串打印出來
- <s:property value="admin" default="管理員"/>
爲admin屬性設置默認值,若是valuestack中沒有則打印默認值
- <s:property value="'<hr/>'" escape="false"/>
默認爲true,將標籤轉譯成字符顯示,而不是直接顯示標籤。
false時,不轉譯,即瀏覽器直接顯示標籤樣式。
2.set 往指定或非指定範圍內設定變量並指定值
經常使用於給actioncontext中的param中的變量命名 api
- <s:set var="adminName" value="username" />
將名爲adminName的變量設置到request和ActionContext中
值爲username的值,此時
- <s:property value="#request.adminName" />
- <s:property value="#adminName" />
均可以將adminName的值顯示
- <s:set name="adminPassword" value="password" scope="page"/>
爲adminPassword變量設定範圍,name=這種寫法已經被廢棄
- <s:set var="adminPassword" value="password" scope="session"/>
上面代碼顯示,
當scope(範圍)爲session時,
在debug標籤中看到actionContext中的session有值,
- <s:property value="#session.adminPassword"/>
因此必須從session中取而不能直接取值。
3.bean 建立name指定的類的對象並用var命名
不用var命名,會只在值棧中壓入建立的對象,
標籤結束時消除對象,因此標籤外訪問不到。
反之,則在stackcontext中,標籤結束後一樣能夠取到。
- <s:bean name="com.bjsxt.struts2.tags.Dog" var="myDog">
- <s:param name="name" value="'oudy'"></s:param>
- </s:bean>
param屬性爲對象的成員變量設置值,name爲名,value爲值。
注意value爲ognl因此字符串要加單引號。
4.include 包含英文文件(中文會出問題)
- <s:include value="/_include1.html"></s:include>
或者
- <s:set var="incPage" value="'/_include1.html'" />
- <s:include value="%{#incPage}"></s:include>
%{}的意思爲將大括號中的內容強制當成ognl表達式
5.if elseif
url傳參數後在actionContext中的parameters中會有對應參數和值
- <s:property value="#parameters.age[0]" /><!--能夠查看參數age的值-->
- <s:if test="#parameters.age[0] < 0">wrong age!</s:if>
- <s:elseif test="#parameters.age[0] < 20">too young!</s:elseif>
- <s:else>yeah!</s:else>
6.iterator
- <s:iterator value="{1,2,3}">
- <s:property/>|
- </s:iterator>
ognl{}內爲集合,iterator標籤將集合中的內容遍歷
由<s:property/>依次打印出來
- <s:iterator value="{'aaa', 'bbb', 'ccc'}" var="x">
- <s:property value="#x.toUpperCase()"/> |
- </s:iterator>
每次遍歷將集合的元素賦予x,
在property標籤中調用其轉換大寫方法轉換爲大寫
- <s:iterator value="{'aaa', 'bbb', 'ccc'}" status="status">
- <s:property/> |
- 遍歷過的元素總數:<s:property value="#status.count"/> |
- 遍歷過的元素索引:<s:property value="#status.index"/> |
- 當前是偶數?:<s:property value="#status.even"/> |
- 當前是奇數?:<s:property value="#status.odd"/> |
- 是第一個元素嗎?:<s:property value="#status.first"/> |
- 是最後一個元素嗎?:<s:property value="#status.last"/>
- </s:iterator>
在iterator中有個狀態標籤status,有許多屬性,如元素總數,索引,奇偶等,
- <s:iterator value="#{1:'a', 2:'b', 3:'c'}" >
- <s:property value="key"/> | <s:property value="value"/>
- </s:iterator>
ognl中的map寫法爲 鍵:值
用<s:property value="key">取鍵,value="value"取值
- <s:iterator value="#{1:'a', 2:'b', 3:'c'}" var="x">
- <s:property value="#x.key"/> | <s:property value="#x.value"/>
- </s:iterator>
用var=x表明其中一個條目,value=#x.key取這個條目的鍵,#x.value取這個條目的值
7.fielderror當action類中
this.addFieldError("fielderror.test", "wrong!");
前臺能夠用fielderror將其顯示
- <s:fielderror fieldName="fielderror.test" theme="simple"></s:fielderror>
8.ui
疑問 struts.xml中的constant標籤有哪些屬性
- <constant name="struts.devMode" value="true"></constant> 開啓熱部署(開發模式)
- <constant name="struts.ognl.allowStaticMethodAccess" value="true"><constant> 容許訪問靜態方法
- <constant name="struts.i18n.encoding" value="GBK" />
解決中文問題
- <constant name="struts.custom.i18n.resource" value="XXXX">
- </constant>
國際化全局配置
9.struts Exception handling—聲明式異常處理
在struts中 class中的方法能夠在捕獲異常後將其拋出,
這樣能夠支持struts的聲明式處理任何異常。
在struts.xml中
- <global-results>
- <result name="error">/error.jsp</result>
- </global-results>
- <global-exception-mappings>
- <exception-mapping result="error"exception="java.lang.Exception">
- </exception-mapping>
- </global-exception-mappings>
必須把results寫前面!
對異常作出映射,當發生java.lang.Exception時,返回error這個result.
10.struts <default-action-ref >的bug問題
該設置不會解析action的方法只會簡單的將result返回BUG。
要想設置首頁,目前只能在web.xml中配置
- <welcome-file-list>
- <welcome-file>index</welcome-file>
- </welcome-file-list>
11.i18n:支持程序國際化
1.i18n原理
a)ResourceBundle和Locale的概念
- ResourceBundle res = ResourceBundle.getBundle("app", Locale.CHINA);
- System.out.println(res.getString("welcome.msg" ));
b)資源文件
app_en_US.properties app_英語縮寫_美國.properties
內容: welcome.msg=hello,sir
app_zh_CH.properties app_中華縮寫_中國.properties
c)native2ascii jdk/bin/native2ascii 能夠將中文轉換成iso8859-1
2.Struts的資源文件
a)app級 見原理
b)propertiesEditor插件
i. 解壓
ii. features plugin 覆蓋到myeclipse中的eclipse目錄裏
3.Action級別國際化
a)jsp中
- <s:property value="getText('login.username')"/>
這裏能夠直接調用方法說明action中有這個方法
這個方法實際上是Actionsupport中的方法
b)LoginAction_en_US.properties中
login.username=username:
login.password=password:
login.login=login
4.package級別國際化 在包內
package_en_US.propertiesss
5.全局級別國際化 (經常使用)
XXXX_en_US.properties 在src目錄內
在struts.xml中配
- <constant name="struts.custom.i18n.resource" value="XXXX">
- </constant>
6.動態字符的國際化
properties中
welcome.msg=welcome:{0}
jsp文件中
- <s:text name="welcome.msg">
- <s:param value="username"></s:param>
- </s:text>
7.動態語言切換
struts中能夠直接在url後傳參數實現動態語言切換
"admin/lang?request_locale=en_US"
12.自定義攔截器
- <package name="test" namespace="/" extends="struts-default">
- <interceptors>
- <interceptor name="my" class="com.bjsxt.interceptor.MyInterceptor"> </interceptor>
- </interceptors>
-
- <action name="test" class="com.bjsxt.action.TestAction">
- <result>/test.jsp</result>
- <interceptor-ref name="my"></interceptor-ref>
- <interceptor-ref name="defaultStack"></interceptor-ref><!--這句話必須寫不然沒有系統子代的interceptor -->
- </action>
- </package>
13.使用struts的token攔截器
- <interceptor-ref name="defaultStack">
- </interceptor-ref>
- <interceptor-ref name="token">
- </interceptor-ref>
- <result name="invalid.token">/error.jsp</result>
最後一句寫明當返回爲invalid.token時的結果頁面