struts2 複習

很久沒用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

[xhtml]  view plain copy print ?
  1. <action name="Student*" class="com.bjsxt.struts2.action.StudentAction" method="{1}">  
  2. <result>/Student{1}_success.jsp</result>  

*代替字符串,{1}表明第一個*所匹配的字符串。
[c-sharp]  view plain copy print ?
  1. <action name="*_*" class="com.bjsxt.struts2.action.{1}Action" method="{2}">  
  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&parameter=XXX.使用這個方法時,在action中要本身new一個模型。

10.
[c-sharp]  view plain copy print ?
  1. <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的標籤來將程序中對用戶的提示信息打印到前臺頁面:
在後臺 使用
[java]  view plain copy print ?
  1. this.addFieldError("name","name is error");  

其中name爲action中的屬性,"name is error"爲錯誤信息的提示 web

[c-sharp]  view plain copy print ?
  1. <s:fielderror fieldName="name" />  

將帶有簡單格式的提示信息打印到前臺
首先,在前臺頁面中包含 spring

[xhtml]  view plain copy print ?
  1. <%@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中的方法
[java]  view plain copy print ?
  1. request = (Map)ActionContext.getContext().get("request");  
  2. session = ActionContext.getContext().getSession();  
  3. application = ActionContext.getContext().getApplication();  

獲得map類型的 request,session,application.
還能夠經過put方法對這些名值對進行賦值。
在前臺頁面,能夠經過
[xhtml]  view plain copy print ?
  1. <s:property value="#request.r1"/> | <%=request.getAttribute("r1") %> <br />  
  2. <s:property value="#session.s1"/> | <%=session.getAttribute("s1") %> <br />  
  3. <s:property value="#application.a1"/> | <%=application.getAttribute("a1") %> <br />  

來拿到所設置的request、session、application.既用#key來訪問或者用最原始的jsp語言來訪問。

二(經常使用)、
一樣設置三個成員變量 但使用範型
[java]  view plain copy print ?
  1. private Map<String, Object> request;  
  2. private Map<String, Object> session;  
  3. private Map<String, Object> application;  

而後設置set方法,由struts將頁面元素對象自動設置進去(實現RequestAware,SessionAware,ApplicationAware),
而後調用put方法,往進寫東西。

3、
一樣設置三個成員變量 但類型不一樣
[java]  view plain copy print ?
  1. private HttpServletRequest request;  
  2. private HttpSession session;  
  3. private ServletContext application;  

而後初始化
[java]  view plain copy print ?
  1. request = ServletActionContext.getRequest();  
  2. session = request.getSession();  
  3. application = session.getServletContext();  

而後由request.setAttribute("r1", "r1")往進設置值。

4、
一樣設置三個成員變量
[java]  view plain copy print ?
  1. private HttpServletRequest request;  
  2. private HttpSession session;  
  3. private ServletContext application;  
  4. //初始化  
  5. public void setServletRequest(HttpServletRequest request) {  
  6.     this.request = request;  
  7.     this.session = request.getSession();  
  8.     this.application = session.getServletContext();  
  9. }  
  10. //而後由request.setAttribute("r1", "r1")設值。  


13.模塊包含
在struts.xml中能夠將其餘xml文檔包含
[xhtml]  view plain copy print ?
  1. <include file="XXXX.xml" />  

這樣的好處是,多個模塊能夠同時開發,而後包含就能夠協做工做。

14.默認action
在url的namespace後什麼都不敲入或敲入不存在的action時,訪問默認的action
[xhtml]  view plain copy print ?
  1. <default-action-ref name="index"></default-action-ref>  

而後再jsp中使用
[xhtml]  view plain copy print ?
  1. <s:property value="r"/>  

接受參數。
●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

[xhtml]  view plain copy print ?
  1. <result type="chain">  
  2.        <param name="actionName">adfadf</param>  
  3.        <param name="namespace">/XXXXXX</param>  
  4. </reuslt>  

在struts-2.2.1.1-docs/struts-2.2.1.1/docs/chain-result.html可查

16.global-results全局結果集在,同一個package中你們能夠共用的結果視圖
[xhtml]  view plain copy print ?
  1. <global-results>  
  2.     <result name="mainpage">/main.jsp</result>  
  3. </global-results>  

其餘package中也想使用此package的result,則extends="packagename"
[xhtml]  view plain copy print ?
  1. <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}
[xhtml]  view plain copy print ?
  1. <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
[xhtml]  view plain copy print ?
  1. <s:property value="username"/>   

將username屬性的值打印出來
[xhtml]  view plain copy print ?
  1. <s:property value="'username'"/>   

將username字符串打印出來
[xhtml]  view plain copy print ?
  1. <s:property value="admin" default="管理員"/>   

爲admin屬性設置默認值,若是valuestack中沒有則打印默認值
[xhtml]  view plain copy print ?
  1. <s:property value="'<hr/>'" escape="false"/>  

默認爲true,將標籤轉譯成字符顯示,而不是直接顯示標籤。
false時,不轉譯,即瀏覽器直接顯示標籤樣式。

2.set 往指定或非指定範圍內設定變量並指定值
經常使用於給actioncontext中的param中的變量命名 api

[xhtml]  view plain copy print ?
  1. <s:set var="adminName" value="username" />   

將名爲adminName的變量設置到request和ActionContext中
值爲username的值,此時
[xhtml]  view plain copy print ?
  1. <s:property value="#request.adminName" />  
  2. <s:property value="#adminName" />  

均可以將adminName的值顯示
[xhtml]  view plain copy print ?
  1. <s:set name="adminPassword" value="password" scope="page"/>  

爲adminPassword變量設定範圍,name=這種寫法已經被廢棄
[xhtml]  view plain copy print ?
  1. <s:set var="adminPassword" value="password" scope="session"/>  

上面代碼顯示,
當scope(範圍)爲session時,
在debug標籤中看到actionContext中的session有值,
[xhtml]  view plain copy print ?
  1. <s:property value="#session.adminPassword"/>  

因此必須從session中取而不能直接取值。

3.bean 建立name指定的類的對象並用var命名
不用var命名,會只在值棧中壓入建立的對象,
標籤結束時消除對象,因此標籤外訪問不到。
反之,則在stackcontext中,標籤結束後一樣能夠取到。
[xhtml]  view plain copy print ?
  1. <s:bean name="com.bjsxt.struts2.tags.Dog" var="myDog">  
  2.     <s:param name="name" value="'oudy'"></s:param>  
  3. </s:bean>  

param屬性爲對象的成員變量設置值,name爲名,value爲值。
注意value爲ognl因此字符串要加單引號。

4.include  包含英文文件(中文會出問題)
[xhtml]  view plain copy print ?
  1. <s:include value="/_include1.html"></s:include>  

或者
[xhtml]  view plain copy print ?
  1. <s:set var="incPage" value="'/_include1.html'" />  
  2. <s:include value="%{#incPage}"></s:include>  

 %{}的意思爲將大括號中的內容強制當成ognl表達式

5.if elseif
url傳參數後在actionContext中的parameters中會有對應參數和值
[xhtml]  view plain copy print ?
  1. <s:property value="#parameters.age[0]" /><!--能夠查看參數age的值-->  
  2. <s:if test="#parameters.age[0] < 0">wrong age!</s:if>  
  3. <s:elseif test="#parameters.age[0] < 20">too young!</s:elseif>  
  4. <s:else>yeah!</s:else>  

6.iterator
[xhtml]  view plain copy print ?
  1. <s:iterator value="{1,2,3}">  
  2.     <s:property/>|  
  3. </s:iterator>  

ognl{}內爲集合,iterator標籤將集合中的內容遍歷
由<s:property/>依次打印出來
[xhtml]  view plain copy print ?
  1. <s:iterator value="{'aaa', 'bbb', 'ccc'}" var="x">  
  2.     <s:property value="#x.toUpperCase()"/> |  
  3. </s:iterator>  

每次遍歷將集合的元素賦予x,
在property標籤中調用其轉換大寫方法轉換爲大寫
[xhtml]  view plain copy print ?
  1. <s:iterator value="{'aaa', 'bbb', 'ccc'}" status="status">  
  2.     <s:property/> |  
  3.     遍歷過的元素總數:<s:property value="#status.count"/> |  
  4.     遍歷過的元素索引:<s:property value="#status.index"/> |  
  5.     當前是偶數?:<s:property value="#status.even"/> |  
  6.     當前是奇數?:<s:property value="#status.odd"/> |  
  7.     是第一個元素嗎?:<s:property value="#status.first"/> |  
  8.     是最後一個元素嗎?:<s:property value="#status.last"/>  
  9. </s:iterator>  

在iterator中有個狀態標籤status,有許多屬性,如元素總數,索引,奇偶等,
[xhtml]  view plain copy print ?
  1. <s:iterator value="#{1:'a', 2:'b', 3:'c'}" >  
  2.     <s:property value="key"/> | <s:property value="value"/>  
  3. </s:iterator>  

ognl中的map寫法爲 鍵:值 
用<s:property value="key">取鍵,value="value"取值
[xhtml]  view plain copy print ?
  1. <s:iterator value="#{1:'a', 2:'b', 3:'c'}" var="x">  
  2.     <s:property value="#x.key"/> | <s:property value="#x.value"/>  
  3. </s:iterator>  

用var=x表明其中一個條目,value=#x.key取這個條目的鍵,#x.value取這個條目的值

7.fielderror當action類中    
this.addFieldError("fielderror.test", "wrong!");
前臺能夠用fielderror將其顯示
[xhtml]  view plain copy print ?
  1. <s:fielderror fieldName="fielderror.test" theme="simple"></s:fielderror>  

8.ui
疑問 struts.xml中的constant標籤有哪些屬性
[xhtml]  view plain copy print ?
  1. <constant name="struts.devMode" value="true"></constant> 開啓熱部署(開發模式)  
  2. <constant name="struts.ognl.allowStaticMethodAccess" value="true"><constant> 容許訪問靜態方法  
  3. <constant name="struts.i18n.encoding" value="GBK" />  

解決中文問題
[xhtml]  view plain copy print ?
  1. <constant name="struts.custom.i18n.resource" value="XXXX">  
  2.    </constant>  

國際化全局配置

9.struts Exception handling—聲明式異常處理
在struts中 class中的方法能夠在捕獲異常後將其拋出,
這樣能夠支持struts的聲明式處理任何異常。
在struts.xml中
[xhtml]  view plain copy print ?
  1. <global-results>  
  2.     <result name="error">/error.jsp</result>  
  3. </global-results>  
  4. <global-exception-mappings>  
  5.     <exception-mapping result="error"exception="java.lang.Exception">  
  6.     </exception-mapping>  
  7. </global-exception-mappings>  

必須把results寫前面!
對異常作出映射,當發生java.lang.Exception時,返回error這個result.

10.struts <default-action-ref >的bug問題
該設置不會解析action的方法只會簡單的將result返回BUG。

要想設置首頁,目前只能在web.xml中配置
[xhtml]  view plain copy print ?
  1. <welcome-file-list>  
  2.    <welcome-file>index</welcome-file>  
  3. </welcome-file-list>  


11.i18n:支持程序國際化
 1.i18n原理
  a)ResourceBundle和Locale的概念
 
[java]  view plain copy print ?
  1. ResourceBundle res = ResourceBundle.getBundle("app", Locale.CHINA);  
  2. 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中
 
[xhtml]  view plain copy print ?
  1. <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中配
  
[xhtml]  view plain copy print ?
  1. <constant name="struts.custom.i18n.resource" value="XXXX">  
  2.    </constant>  

 6.動態字符的國際化
   properties中
   welcome.msg=welcome:{0}
   jsp文件中
  
[xhtml]  view plain copy print ?
  1. <s:text name="welcome.msg">  
  2.     <s:param value="username"></s:param>  
  3.    </s:text>   

 7.動態語言切換
   struts中能夠直接在url後傳參數實現動態語言切換
   "admin/lang?request_locale=en_US"

12.自定義攔截器
[xhtml]  view plain copy print ?
  1. <package name="test" namespace="/" extends="struts-default">  
  2.     <interceptors>  
  3.         <interceptor name="my" class="com.bjsxt.interceptor.MyInterceptor">            </interceptor>  
  4.     </interceptors>  
  5.   
  6.     <action name="test" class="com.bjsxt.action.TestAction">  
  7.         <result>/test.jsp</result>  
  8.         <interceptor-ref name="my"></interceptor-ref>  
  9.         <interceptor-ref name="defaultStack"></interceptor-ref><!--這句話必須寫不然沒有系統子代的interceptor -->  
  10.     </action>  
  11. </package>  


13.使用struts的token攔截器
[xhtml]  view plain copy print ?
  1. <interceptor-ref name="defaultStack">  
  2.     </interceptor-ref>  
  3.     <interceptor-ref name="token">  
  4. </interceptor-ref>  
  5. <result name="invalid.token">/error.jsp</result>  
最後一句寫明當返回爲invalid.token時的結果頁面
相關文章
相關標籤/搜索