struts筆記-struts的理解





struts2框架引入到web項目中:
1,把struts2相關的jar包引入到項目中。
2把struts的配置文件直接放到src下面,名字叫做strut.xml(運行是配置文件被框架自動讀取)
注意:如果struts.xml文件中不能自動提示標籤,把相應的dtd文件配置上去。
3在web.xml文件中配置struts框架過濾器
第一種filter的配置:(這是struts2框架2.0使用的配置方式)
 <filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
 </filter>
 <filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
 </filter-mapping>


     第二種filter配置:(這是struts2框架2.0以上使用的配置方式 同時2.0以上的版本也可以使用上面的配置方式)
這個過濾器類是2.0版本以上新增加的類。
 <filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
 </filter>
 <filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
 </filter-mapping>


這個過濾器的作用:攔截struts框架中的action。

注意:如果不配置這個filter,struts框架就不能夠正常工作。


2.struts2框架中的Action
struts2框架底層還是封裝了Servlet的相關內容來實現出來的。只不過struts2框架除了servlet的功能
以外還擴展出來很多其他的功能,同時還大大簡化了以前在servlet中繁瑣的操作。
在struts框架中,有一種類就是以前我們在web項目中所使用的servlet,那麼這中類,在struts2框架中被稱爲
Action
所以Action其實也是一種java類,比servlet功能更加強大的java類。同時還比servlet中的操作簡單。


3.爲什麼Action會有比servlet強大的功能以及簡潔的操作?
因爲我們在web.xml文件中配置了struts2框架中專門的過濾器。用做攔截訪問action的請求,攔截住以後。就
可以給Action添加很多豐富的功能。
4,如何去寫一個struts框架中的Action:
三種方式:
1.直接寫一個類,不需要繼承類和實現某個接口,但這個類裏面一定要有一個固定的方法(也是不一定的可以用
method="test"這個屬性指定。):
public String execute(){

return "";
}
注意:execute方法一定要返回String類型的對象。每一個字符串都可以對應一種跳轉的頁面。
(字符串是自己定義的,跳轉頁面也是自己在struts.xml中定義的。)


2.實現一個指定的接口:Action
只有一個抽象方式 execute();
同時還要五個String類型的靜態屬性:ERROR,SUCCESS,INPUT,NONE,LOGIN


3.繼承一個父類ActionSupport



5.寫完Action類後需要在struts.xml文件中進行配置。
在struts.xml配置Action的目的和作用:
通知struts2框架我們寫的這個類是一個Action,將來struts框架中要給這個類創建對象,調用方法以及加入
更多豐富的功能。
例如:
   <package name="test" extends="struts-default" namespace="/test">
<action name="MyTest">
<result>/index.jsp</result>
</action>
   
        <action name="test1" class="com.briup.web.action.ActionTest1">
       <result name="myFirstAction">/success.jsp</result>
       <result name="myError">/error.jsp</result>
        </action>


   </package>


   name="test1"表示當前配置這個action的名字爲test1,這個名字是隨便起的,可以和action類的名字相同或者不同.
   同時將來瀏覽器中的地址欄裏面就是要出現這個名字來訪問當前這個action類
   
   class=".."表示當前配置的action對應的是哪一個java類,我們可以配置一個action,但是這個action可以沒有對應
   任何java類。就像上面配置的MyTest的例子.


   <result>標籤表示將來這個action訪問完了之後有哪些跳轉.
   
   <result name="myError">/error.jsp</result> 表示當前這個action如果返回的字符串是myError,就那麼頁面就
   跳轉到/error.jsp中


   注意:每一個action被訪問完之後都會有一個字符串類型的返回值,即使訪問一個沒有任何java類對應action的時候,
   這個action也會默認返回字符串:success
   <result name="success">  <==>  <result>
   <result>標籤中的name屬性默認值就是success
   


   <package name="test" extends="struts-default" namespace="/test">
   <package>:一個struts.xml文件中可以配置多個<package>標籤,一個<package>標籤裏面可以配置多個<action>標籤,
   一個<action>標籤裏面可以配置多個<result>
   name="test"標籤給當前package起一個名字爲test,作用:1.唯一標識當前這個package。
2.方便package與package之間通過這個名字來實現繼承的關係。


    extends="struts-default" 標籤當前這個package繼承了另外一個名字叫做struts-default的package,
    這個package在struts2的核心jar包中的struts-default.xml文件中定義的,裏面定義了很默認的配置.


   注意:我們在struts2中定義的所有package,都會是直接或者間接的繼承了struts-default這個package.
   
   namespace="/test" 表示當前package的命名空間爲/test,將來這個package裏面的所有的action在被訪問的時候,
   路徑裏面都要加上這個命名空間.






特殊的action配置,:使用通配符來配置,
使用前提:原來需要配置的多個action名字或者類的名字是有一定的規律的。
    例如:原來需要配置這樣三個action:
<action name="test1" class="com.briup.web.action.ActionTest1">
<result>/success.jsp</result>
<result name="error">/error.jsp</result>
</action>


<action name="test2" class="com.briup.web.action.ActionTest2">
<result>/success.jsp</result>
<result name="error">/error.jsp</result>
</action>


<action name="test3" class="com.briup.web.action.ActionTest3">
<result>/success.jsp</result>
<result name="error">/error.jsp</result>
</action


這時候,我們就可以使用通配符配置一個action來代替這三個action
<action name="test*" class="com.briup.web.action.ActionTest{1}">
<result>/success.jsp</result>
<result name="error">/error.jsp</result>
</action>
   {1}代表的前面name屬性中所出現的第一個*號,如果有第二個*,可以用{2}來表示
   text*就是將來在瀏覽器中輸入的這個action名字,如果輸入的是test1,那麼這個*好就代表1,如果輸入的是
   testlogin ,那麼這個*好就代表login。
   注意:如果原本需要配置的多個action,沒有非常明顯的規律,就不要使用這種方法配置。
6.在struts.xml文件中配置struts2框架的屬性.
  <constant name="struts.devMode" value="true"></constant>
  作用:修改完struts.xml配置文件後不需要重新啓動服務器。但要注意在開發完之後,要重新設置爲false。


<constant name="struts.custom.i18n.resources" value="message"></constant>
作用:這冊國際化的資源文件(value屬性指的是文件名的前綴)






7.action 的特點及其訪問:
http://localhost:8002/jd1307_struts2/namespace/actionName.action
servlet是線程不安全的,因爲servlet是單例,struts2框架中的action是線程安全的,因爲每次
訪問都會創建一個新的Action對象,所以在action裏面可以隨便的定義成員變量(只有成員變量纔有
線程安全的問題
);




 訪問:
    (strut2框架的版本不同默認情況有所不同)
    默認情況下,訪問action的時候,使用namespace/actionName.action或者namespace/actionName就可以訪問的到.
    但是由於不加任何後綴名也可以訪問到這個action,這樣容易和其他資源的訪問產生衝突,比如servlet的訪問.
    所以我們需要配置一下,把action訪問規定成,只能使用後綴名.action或者是.do 或者是其他形式來訪問.
    
    //可以使用.action或者.do來訪問
    <constant name="struts.action.extension" value="action,do"></constant>
    //只能使用.action
    <constant name="struts.action.extension" value="action"></constant>






8.訪問action的時候,action中的方法的調用:
1,默認情況下,訪問action會調用action中的exexute方法,這個方法執行完的時候,會返回一個字符串。
然後根據字符串進行跳轉。
2,可以在<action>標籤裏面加上一個method屬性,來指明將來訪問這個action的時候會調用哪個方法。
例如:
<action name="test" class="  " method="login">
注意:我們可以定義多個名字不同的action對應相同的java類,這個我們也可以用method來指定方面,這是我們
也是可以訪問到一個類中的不同的方法。
          <action name="test" class="  " method="login">
          <action name="test1" class="  " method="register">
 這樣可以使用test,test1兩個不同名字的action就是訪問到同一個類中的兩個不同的方法,:login,
 register但是login方法和register方法必須是和execute方法類似 ,有String類型的返回值。
3.地址欄中動態指定要調用的方法
        例如:
<action name="test" class="類A">
類A裏面有倆個方法:register login

默認情況下地址欄中通過test.action來訪問這個action會訪問到它的execute方法,同時我們還可以在地址欄
中動態的指定要訪問的方法:
test!login.action  這樣就能訪問到名字爲test的action對應類A中的login方法了.


9。配置全局的跳轉:
<global-results>
    <result name="success">/Msg.jsp</result>
    <result name="myError">/error.jsp</result>
 </global-results>
 作用:將來在任何的其他action中,如果有需要返回success字符串跳轉到Msg.jsp或者myError字符串跳轉到
 error.jsp的時候,就不需要在單獨的哦定義,因爲已經把這兩個跳轉定義成了全局的跳轉,對當前package裏面的所有
 action都起作用,同時還可以在某一個action再重新定義一些這兩個跳轉,這個時候全局跳轉就不會對這個action起
 作用了,(覆蓋了全局跳轉)


10.配置package中默認的action
<!-- 配置默認的action -->
    <default-action-ref name="MyTest"></default-action-ref>
    作用:如果地址欄中訪問量當前package下面一個不存在的action的時候,正常情況下會直接報錯的,
    錯誤信息顯示這個
    action找不到,但我們一旦配置了這個默認的action之後,那麼再去訪問一個不存在的actin就不會保持了
    而是直接就去訪問這個默認的action
    這個默認的action需要在當前package裏面定義出來,並且在
    <default-action-ref name="MyTest"></default-action-ref>裏面引用一下。
    注意:訪問某個package下面action的時候有幾種錯誤情況:
1,action找不到
2,action找到了但是action對應的類找不到。
3.action找到了,對應的類找到了,但是在類中要執行的方法沒有找到
4,action找到了,對應的類找到了,但是在類中要執行的方法找到了,但是方法返回的字符串在<result>
中沒有定義。
5.action找到了,對應的類找到了,但是在類中要執行的方法找到了,但是方法返回的字符串在<result>
中也定義了,但是跳轉頁面沒有找到。
 
  配置默認的action實現類:
 <!-- 配置默認的實現類 -->
    <default-class-ref class="com.briup.web.action.ActionText"></default-class-ref>


11.action中跳轉的方式:
 <result name="" type="">..</result>
name屬性指的是跳轉的名字,也是action返回的字符串,
type屬性指的是跳轉的類型,常用到的有以下四種:


  dispatcher:從一個action裏面跳轉到一個頁面中(服務器內部跳轉)這個屬性是type的默認值。
  chain:從一個action裏面跳轉到另外一個action(服務器內部跳轉)
  1.同一個package下面的action跳轉:
       /test下面的action跳轉到/test下面的action
       <result type="chain">methodTest1</result>
       或者:
       <result type="chain">
   <param name="actionName">methodTest1</param>
   <param name="namespace">/test</param>
       </result>


       2.不同的倆個package下面的action跳轉
       /test下面的action跳轉到/user下面的action
      <result type="chain">
   <param name="actionName">mytest</param>
   <param name="namespace">/user</param>
      </result>




  redirect:從一個action裏面客戶端重定向到一個頁面中。
<result name="success" type="redirect">/Msg</result>


  redirectAction:從一個action裏面客戶端重定向到一個action中。


1.同一個package下面的action跳轉:
       /test下面的action跳轉到/test下面的action
       <result type="redirectAction">methodTest1</result>
       或者
       <result type="redirectAction">
   <param name="actionName">methodTest1</param>
   <param name="namespace">/test</param>
       </result>


       2.不同的倆個package下面的action跳轉
       /test下面的action跳轉到/user下面的action
      <result type="redirectAction">
   <param name="actionName">mytest</param>
   <param name="namespace">/user</param>
      </result>




12.strut2框架中的攔截器(interceptor)
    1.什麼是攔截器(interceptor)
      攔截器是struts2框架中提供的一種java類,
         作用:是用來攔截那些訪問action的請求,攔截到這些請求後,可以豐富action的功能或者
額外的處理一下訪問action的類。
    2.攔截器(interceptor)是如果工作的
       a,要有一個攔截器的類(可能是struts2框架自帶的或者我們自己定義的一個類)
       b,在配置文件中把這個攔截器配置出來。
       c,指明這個攔截器要攔截哪一個或者哪一些action
       d,客戶端發送一個請求訪問一個被攔截器攔截的action
       e,這個請求會先被struts2的filter所攔截,filter會先檢查這個請求是不是請求的action,如果是action
       的話,那麼會再檢查這個action有沒有被定義的攔截器所攔截,如果有就把這個請求較高攔截器去處理。


    3.如何自定義一個攔截器
strut2框架已經寫好了很多攔截器(在struts2的核心jar包),同時也把這樣攔截器配置在配置文件裏面(
在struts-default.xml中)
除此以外,我們還能寫自己的攔截器。
要寫一個攔截器,首先要實現一個接口:com.opensymphony.xwork2.interceptor.Interceptor
      
      例如:
public class MyInterceptor implements Interceptor{


public void destroy() {

System.out.println("in destory() of MyInterceptor");

}


public void init() {
System.out.println("in init() of MyInterceptor");

}


public String intercept(ActionInvocation ai) throws Exception {

System.out.println("before...");
//ai.invoke()其實就是幫我們去調用action中將要執行的方法,比如execute方法
//ai.invoke()的放回值其實就是action中方法執行完返回的字符串
String s = ai.invoke();
System.out.println("after...");
return s;
}


}

4.攔截器棧
      當前一個action需要被多個攔截器攔截的時候,正常情況下,我們需要在這個action中去引用要使用到的多個
      攔截器,但是我們可以使用一個攔截器棧去包含那幾個攔截器,然後在action中直接引用這個攔截器棧就可以了.
      1,一個攔截器棧可以包含多個攔截器
      2,一個攔截器棧也可以包含多個攔截器棧
      3.定義攔截器或者攔截器棧都要在<interceptors>標籤中
      例如:
<interceptors>
<interceptor name="myInterceptor" class="com.briup.web.interceptor.MyInterceptor"></interceptor>
<interceptor-stack name="myStack">
<interceptor-ref name="myInterceptor"></interceptor-ref>
<!-- 這是struts-default.xml文件中定義的一個攔截器 -->
<interceptor-ref name="params"></interceptor-ref>
<!-- 這是struts-default.xml文件中定義的一個攔截器棧 -->
<interceptor-ref name="basicStack"></interceptor-ref>
</interceptor-stack>
</interceptors>


<interceptors>
<interceptor name="myInterceptor" class="com.briup.web.interceptor.MyInterceptor"></interceptor>
<interceptor-stack name="myStack">
<interceptor-ref name="myInterceptor"></interceptor-ref>
<!-- 這是struts-default.xml文件中定義的一個攔截器棧 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
5.默認攔截器/攔截器棧
  在一個package中,我們可以把一個攔截器或者攔截器棧聲明爲一個默認的攔截器/攔截器棧
  作用:將來這個package中所有的action都會被這個默認的攔截器/攔截器棧所攔截。
         例如:
//myStack可以是一個攔截器/攔截器棧
       <default-interceptor-ref name="myStack"></default-interceptor-ref>
,一般情況下,我們所寫的任何action都會被一個叫做defaultStack的攔截器所攔截,這個攔截器棧裏面
中包含了十幾個攔截器,這些攔截器給我們的action提供了很多豐富的功能。
因爲我們寫所有的package都是直接或間接的繼承了struts-default.xml文件中的一個名字叫struts-default的
package,struts-default包中又把名字叫defaultStack的攔截器棧配置成了一個默認的攔截器棧,
那麼我們的package就把這個配置繼承了過來,所有我們的action正常情況下都會被defaultStack所攔截.
但是如果我們一旦指明瞭某一個action被我們所寫的一個攔截器/攔截器棧所攔截,那麼這個action就不會
被defaultStack攔截了.所以我們可以在action中主動的再聲明這個action被defaultStack所攔截,或者把
defaultStack加入到我們自定義的攔截器棧裏面(攔截器棧可以包含攔截器棧。)


 6.package之間的繼承
我們可以專門再定義一個package,在這個package裏面我們只做攔截器/攔截器棧的定義:
<!-- 在這個package中,我們只定義攔截器/攔截器棧 -->
<package name="MyInter" extends="struts-default" namespace="/">


<interceptors>
<interceptor name="myInterceptor" class="com.briup.web.interceptor.MyInterceptor"></interceptor>
<interceptor-stack name="myStack">
<interceptor-ref name="myInterceptor"></interceptor-ref>
<!-- 這是struts-default.xml文件中定義的一個攔截器棧 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 聲明默認攔截器/攔截器棧 -->
<!-- 當前包中所有的action都會被這個myStack所攔截器 -->
<!-- 繼承了當前包的其他包裏面的所有action也會被這個myStack所攔截器 -->
<default-interceptor-ref name="myStack"></default-interceptor-ref>

</package>


然後我們可以讓其他的package去繼承我們這個MyInter包,這樣以來,
其他包中的action都會被我們這個MyInter包中的默認攔截器棧myStack所攔截了。




    注意:一定要保證action至少是被defaultStack這個攔截器棧所攔截的.


13.攔截器(interceptor)和過濾器(filter)的區別:
相同點:
 1,攔截器和過濾器都是一種Java類。
 2,都能攔截客戶端發過來的請求。
 3,攔截的請求之後都可以做一些相應的處理,最終還可以把這個請求放行。
  4.都需要實現各自相應的接口以及在相應的配置文件中配置.
     不同點:
      1.攔截器(interceptor)是struts2框架中的定義的,過濾器(filter)是web裏面的對象,是J2EE標準裏面定義的.
      2.攔截器(interceptor)只會攔截器訪問action的請求,過濾器(filter)能夠攔截所有請求.
      3.攔截器(interceptor)定義在struts.xml文件中,過濾器(filter)定義在web.xml文件中.
      4.攔截器(interceptor)對象的創建、調用、銷燬是struts2框架負責的,過濾器(filter)對象的創建、
調用、銷燬服務器負責的.


我們自己定義的filter攔截器struts2中的action的問題
      1.可以攔截
      2.需要在web.xml文件中把我們自己的filter配置在struts2的filter的上面纔可以.


      因爲web.xml文件中filter配置的先後順序控制filter起作用的順序,同時如果struts的filter先攔截到
      訪問action的請求後,不會把這個請求交給下面的filter,而是交給了他它內部的攔截器(interceptor)了,
      但是如果我們自己filter攔截到請求之後,還是依然會交給下一個filter,也就是交給struts2的filter.




14.前臺頁面向後臺action中傳參
     第一種情況:
     例如:
       通過頁面要把id=1 name=tom age=20這三個參數傳給action
     
     1.action裏面定義三個成員變量id name age,這個三個變量的名字一定要和所傳變量的名字一致.
     2.提供get/set方法
     3.將來頁面把這三個參數傳過來的時候,struts2框架會自動的幫我們把這個三個參數值放action中的
     三個屬性裏面.(同時還做了類型的轉換)
     注意:這個工作其實是由defaultStack這個攔截器棧裏面的攔截器來完成了.
傳值完成之後,我們只要在execute方法中去直接使用就可以了,不需要做其他事情.
    
    第二種情況:
      在接受到頁面傳值的時候,還可以讓struts2框架直接幫我們把這些接受到的值封裝到一個javabean對象裏面。


      1,action中定義一個User類型的變量
      user,User類中有三個屬性值,id,name,age,同時User類中還有get/set方法
      2,action中給這個user屬性提供get/set方法
      3,頁面向action傳值的時候,參數的名字要寫出user.id=1 user.name=?user.age=?
      我們將來接受到這個參數值以後,struts2的框架會幫我們去創建一個User對象,並且把所傳參數三個值封裝到
      對象的三個屬性中。最後把這個封裝好的對象放到action的user屬性中。




15.從action向頁面傳值
   在action中依然可以像以前在servlet裏面一樣,使用request,session,application向頁面傳值之外,action
   裏面還有兩個獨有的傳值方式:ValueStack,ActionContext


1.ValueStack是一個接口:com.opensymphony.xwork2.util.ValueStack
ActionContext是一個類:com.opensymphony.xwork2.ActionContext
我們可以使用這個倆個類型的對象,從action裏面把值帶到頁面.
    
    2.我們在頁面中,可以通過一個struts2的標籤來看到action傳到頁面中的值:<s:debug/>
    頁面引入標籤庫:<%@taglib uri="/struts-tags" prefix="s" %>


    3.當前action進行跳轉的時候,struts2框架會自動的把當這個action對象本身分別放到ValueStack和
    ActionContext這個倆個對象,然後struts2框架再把這個倆個對象傳給頁面,所以我們在頁面中只要通過這個
 倆個對象,就可以拿到之前放進去的值.(在頁面的debug標籤中,可以看到struts框架放到這倆個對象裏面的action)


    4.除了struts框架自動的向ValueStack和ActionContext裏面放值以外,我們還可以手動的向這倆個對象裏面放值.


    5.如何拿到ValueStack和ActionContext對象
       獲得ActionContext對象:
ActionContext ac = ActionContext.getContext();

       獲得ValueStack對象:
ValueStack vs = ac.getValueStack();


     6.自己向ac和vs中主動放值
       向ActionContext對象中放值:
        ac.put(String,Object);
ac.put("hello","world");
       
       向ValueStack對象中放值:
        User user = new User();
        vs.push(user);
注意:ValueStack是壓的對象,顯示是對象的屬性值,
    
    7.ValueStack的特點(值棧)
      1.把對象放到vs裏面之後,我們從這個vs中是拿不到這個對象的,但是我們直接拿到這個對象的屬性
      以及屬性值。
      注意(vs分三列,Object,PropertyName,PropertyValue:Object中存的是對象,PropertyName裏面放的是
      對象的屬性名字,PropertyValue是放的屬性的值)
       2.從vs中拿值的時候,是從vs中的PropertyName這一列拿值的,拿的是PropertyValue這一列的值(在
dubug中的vs視圖可以看到這些列)
所以如果我們通過vs把一個值傳到頁面,我們不能直接把這個值放到vs裏,因爲這樣拿不到,
我們應該把這個值放到一個對象的屬性裏面,然後再把這個對象放vs中,
這個時候就可以通過vs拿到這個對象的屬性了,也就是我們要傳的值.
        3.每次瀏覽器發送一個新的請求,都會生成一個新的ValueStack對象,上一次的ValueStack對象就沒了,
找不到了.(類似之前學習的request對象的特點)
4.每次創建一個新的ValueStack對象後,會把這個對象放到ActionContext裏面.


     8.ActionContext的特點


        1.向ac裏面放值的時候是通過key-value的形式存放的,key是String類型,value是Object類型,
取值的是同樣通過key拿到value.
2.struts框架默認向這個對象裏面存放的對象(數據)很多,包括request、session、
application、ValueStack、parameters等


        3.每次請求都會創建一個新的ActionContext對象(每次請求打印出ac的地址值可以看出來)
     
     9.注意:使用vs和ac傳值的時候,要使用服務器內部跳轉的方式.


16.在action中訪問web元素(request session application)
   
   1.在struts2框架中,這三個對象分別都有倆個類型:原類型 Map類型
   
   2.原類型:
       HttpServletRequest request
       HttpSession  session
       ServletContext     application


     Map類型:
       Map<String,Object> request
       Map<String,Object> session
       Map<String,Object> application
   
   3.在使用的時候,我們可以選擇使用原類型的request或者選擇使用Map類型的request.
   (session和application也是這樣的情況)
   
   4.不管是原類型的還是Map類型的對象,都是被struts2框架默認存放到了ActionContext對象裏面.
   (使用debug標籤可以看到)




   5.原類型的和Map類型的關係.
      a.使用Map類型的對象,可以降低代碼中對  servlet的API的依賴(降耦)


      b.我們使用原類型大多時候也是存值和取值,而且原類型裏面本身也是封裝了Map對象。
      所以我們使用Map類型的對象也可以完成存值和取值.
      
      c.Map類型的request對象裏面的值(k-v),其實就是複製的原類型的request對象裏面的值(k-v),
      當然原類型的request對象裏面除了k-v類型的鍵值對以外,還有其他的屬性和方法,
      因爲它畢竟是HttpServletRequest類型的對象.
      d.所以原類型的request和Map類型的request對象,我們可以理解爲他們裏面的值(k-v)是相通的,
      相通的意思就是:這個對象裏面有什麼值,那個對象裏就也會什麼值.所以我們在action裏面向Map類型
      的對象中存放一個值(k-v),將來在頁面中同樣是可以使用原類型的request對象那這個值(k-v)取出來的.
      
      注:session和application的情況也是一樣的道理.


    6.在action中如果拿到Map類型和原類型的對象
        
1.獲取Map類型對象
  第一種方式:自己在方法中主動獲得
  ActionContext ac = ActionContext.getContext();
  //獲得Map類型request
  Map<String,Object> request = 
    (Map<String, Object>) ac.get("request");
  
  //獲得Map類型session
           Map<String, Object> session = ac.getSession();
  
  //獲得Map類型application
  Map<String, Object> application = ac.getApplication();
 
 第二種方式:讓struts2框架把Map類型的對象自動的放到action裏(依賴注入)
  1.第一種方式是自己主動拿到這個對象.
  2,第二種方式是自己被動接受這個對象.
實現三個接口,分別可以讓struts2框架把Map類型的request、session、application對象通過調用實現的接口中方法傳給我們的action,在action裏面我們只要接收這三個對象就可以了,那到後可以直接使用.
   三個接口依次爲:
   RequestAware,SessionAware,ApplicationAware


   例如
public class WebActionTest extends ActionSupport implements RequestAware,SessionAware,ApplicationAware{
private Map<String, Object> request;
private Map<String, Object> session;
private Map<String, Object> application;



@Override
public String execute() throws Exception {
//頁面中用原類型的對象去正常值就可以了
request.put("MyName", "tom");
session.put("YourName", "zhansan");
application.put("HerName", "lily");



return SUCCESS;
}


public void setRequest(Map<String, Object> request) {
this.request = request;
}


public void setSession(Map<String, Object> session) {
this.session = session;
}


public void setApplication(Map<String, Object> session) {
this.application = application;
}


}




2.獲取原類型對象
   第一種方式:自己主動獲得
   獲得原類型request對象
   HttpServletRequest req = ServletActionContext.getRequest();
   獲得原類型response對象
   HttpServletResponse res = ServletActionContext.getResponse();
   獲得原類型session對象
   HttpSession sess = req.getSession();
   獲得原類型application對象
   ServletContext app1 = sess.getServletContext();
   或者
   ServletContext app2 = ServletActionContext.getServletContext();


     
   第二種方式:自己被動接收
   struts2框架中提供了一個接口,可以用來獲得原類型的request對象,因爲通過原類型的request對象
   就可以獲得原類型的session對象和原類型的application對象


   實現接口:ServletRequestAware,然後struts2框架會通過action所實現的抽象方法,把原類型
   的request對象自動放到action裏面.


   類似的還有一接口:ServletResponseAware,和上面的效果、用法是一樣的。


17.頁面中獲得action傳過來的值
  在struts2框架所提供的頁面取值方式中,需要使用到倆個東西:struts2框架的標籤、OGNL表達式
  注意:同時我們也可以使用jsp內置對象取值已經使用jstl標籤+EL表達式取值.
    struts2中可以使用的取值方式:
      1.jsp內置對象取值
      2.jstl標籤+EL表達式取值
      3.struts2標籤+OGNL表達式
    注意:OGNL表達式只能寫在struts2的標籤屬性中,在這裏面我們先使用一下struts2的這樣
    一個標籤:<s:property value=""/>,這個標籤的作用就是向頁面輸出值.
    例如:
    <s:property value=" OGNL表達式寫在這 "/>
  一)從ValueStack和ActionContext中取值
     
     1.從ValueStack中取值.
       //注意這個value屬性中的值name,其實就是ongl表達式
       //這個表示從valueStack中取一個名字叫做name的property值
       <s:property value="name"/>
       <s:property value="user"/>
       <s:property value="user.id"/>
       <s:property value="user.name"/>


       注意:從ValueStack中取值的時候,如果Valuestack裏面有倆個名字相同的值,
       我們只能取到最上面的值(從debug標籤中看vs中最上面的值)
(經過一些處理,也可以取到下面的)
     2.從ActionContext中取值.
       要使用ognl表達式通過AC中的key來拿相對於的value值。取值的時候需要加上一個符號:#
       <s:property value="#action.name"/><br>
       <s:property value="#msg"/><br>
       <s:property value="#user"/><br>
       <s:property value="#user.id"/><br>
       <s:property value="#user.name"/><br>
       <s:property value="#user.age"/><br>
       
     3.ActionContext中的parameters、attr、request、session、application等key值.(這些都是AC中的key)


       parameters對應的值中存放的是客戶端所傳過來的參數.
       //接收客戶端傳來的名字爲name的參數值
       <s:property value="#parameters.name"/><br>
       
       //獲得request中的值
       <s:property value="#request.MyName"/><br>
       //獲得session中的值
       <s:property value="#session.MyName"/><br>
       //獲得application中的值
       <s:property value="#application.MyName"/><br>
       
       //默認依次從request、session、appliction中取值,取到了就直接輸出,取不到就算了.
       <s:property value="#attr.MyName"/><br>




  二)還可以使用以前的方式從request、session、application中取值.
   注意:如果我們用request通過key去取值的時候,會先在request裏面找,request裏面找不到
   會到ValueStack裏面找。因爲ValueStack默認也被放在request裏面.
   但是session和application沒有像request的這樣的特點.


   使用jsp腳本代碼取值
   <%=request.getAttribute("name") %><br>
   <%=session.getAttribute("name") %><br>
   <%=application.getAttribute("name") %><br>


   使用EL表達式取值:
    ${requestScope.MyName }<br>
    ${requestScope.name }  <br>
    ${sessionScope.MyName }  <br>
    ${applicationScope.MyName }  <br>
    ${MyName }  <br>
    ${name }  <br>


118.OGNL表達式
   Object Graph Navigation Language
   像之前學習的EL表達式一樣,這個也是一種表達式語言,但是比EL表達式的功能要強.
   EL基本上可以寫在頁面中的任何一個位置
   OGNL只能寫在struts2標籤的屬性值中.
   
   OGNL表達式的使用:
    <h1>輸出文本字符串</h1>
  ${"hello"}//el表達式
 
  ${"1+1"}//el表達式
   <s:property value="'hello'"/>
   <s:property value="'1+1'"/>
   <h1>輸出數學運算式子的結果</h1>
    ${1+1}//el表達式
   <s:property value="1+1"/>
   <s:property value="(1+8)+45*12"/>
   <h1>輸出boolean表達式</h1>
   ${1<2 }//el表達式
     <s:property value="1<2"/>
     <s:property value="1<2||2>0"/>
     <s:property value="1<2&&1<6"/>
     <s:property value="1<2?'hello':'hh'"/>
     ××××××××××××××××××××××××××××××
   1.輸出文本字符串
    <s:property value="'hello'"/><br>
    <s:property value="'hello world'"/><br>
    <s:property value="'1+1'"/><br>
   
   2.輸出數學運算式子的結果
    <s:property value="1+1"/><br>
    <s:property value="((1+1)*4-3)*4-5"/><br>


   3.輸出boolean表達式的結果
    <s:property value="1<2"/><br>
    <s:property value="1 == 2"/><br>
    <s:property value="1 >= 2"/><br>
    <s:property value="1>2||1<0"/><br>
    <s:property value="1>2&&1>0"/><br>
    <s:property value="1>2?'hello':'world'"/><br>
   4.從ValueStack中取值
    <s:property value="name"/><br>
    <s:property value="locale"/><br>
    <s:property value="user"/><br>
    <s:property value="user.id"/><br>
    <s:property value="user.name"/><br>
    <s:property value="user.age"/><br>


   5.從ValueStack中取值的時候,有倆個名字相同的值
     
    <!-- [1]表示去拿到ValueStack(值棧)中第二對象的name屬性值 -->
    <!-- ValueStack(值棧)中對象從上到下的下標依次爲0、1、2、3.... -->
    <s:property value="[1].name"/><br>
   
   6.取到ValueStack中屬性值,如果屬性值是一個對象,還能調用這個對象的方法
    <!-- 注意:只要是能拿到一個對象,就能調用方法,不管這個對象從哪個地方拿到的 -->
    <s:property value="user.getName()"/><br>
    <s:property value="user.say()"/><br>
   
   7.取到ActionContext中value值,如果值是一個對象,還能調用這個對象的方法
    <s:property value="#user.getName()"/><br>
   
   8.調用類中的構造器創建對象,並且調用對象的方法
    <s:property value="new com.briup.bean.User().getId()"/><br>
   
   9.直接調用字符串對象的方法
    <s:property value="'abc'.equals('bcd')"/><br>
    <s:property value="'nihao'.equals('nihao')"/><br>
   10.調用ValueStack中action對象/其他對象的靜態方法
     <!-- 格式:@vs1@靜態方法的名字() -->
     <!-- vs1代表ValueStack中的第一個對象(從上到下) -->
     <!-- vs2代表ValueStack中的第二個對象(從上到下) -->
     <s:property value="@vs1@test()"/><br>
    11.調用JDK中類/自定義類的靜態方法/靜態屬性
     <!-- 格式:@...@... -->
     <!-- 
        第一個@後面要加上類的全名
           如果沒有寫,默認值是: java.lang.*
           雖然有默認值,但是還是要求任何時候都寫明確這個值.
        第二個@後面要加上靜態屬性/靜態方法的名字
   
      -->
    <s:property value="@@PI"/><br>
    <s:property value="@java.lang.Math@PI"/><br>
    <s:property value="@java.lang.Math@random()"/><br>
    <s:property value="@com.briup.bean.User@test()"/><br>


    12.從ActionContext中取值
    <s:property value="#action.name"/><br>
    <s:property value="#msg"/><br>
    <s:property value="#user"/><br>
    <s:property value="#user.id"/><br>
    <s:property value="#user.name"/><br>
    <s:property value="#user.age"/><br>
    
    <s:property value="#parameters.name"/><br>
    <s:property value="#request.MyName"/><br>
    <s:property value="#session.MyName"/><br>
    <s:property value="#application.MyName"/><br>
    
    <s:property value="#attr.MyName"/><br>
    <s:property value="#request"/><br>
    <s:property value="#request.name"/><br>


//這個是OGNL測試的時候所用到的action類和User類


public class GetValueActionTest extends ActionSupport implements RequestAware,SessionAware,ApplicationAware{
private String name;
private User user;
private Map<String,Object> request;
private Map<String,Object> session;
private Map<String,Object> application;

@Override
public String execute() throws Exception {
//System.out.println(this);
user = new User();
user.setId(100);
user.setName("zhangsan");
user.setAge(20);

User u = new User();
u.setId(500);
u.setName("lisi");
u.setAge(30);

ActionContext ac = ActionContext.getContext();
ValueStack vs = ac.getValueStack();
vs.push(u);

ac.put("user",u);
ac.put("msg","hello world");

name = "tom";

request.put("MyName", "tom1");
session.put("MyName", "tom2");
application.put("MyName","tom3");

return SUCCESS;
}

public String myOGNL() throws Exception {
//System.out.println(this);
user = new User();
user.setId(100);
user.setName("zhangsan");
user.setAge(20);

User u = new User();
u.setId(500);
u.setName("lisi");
u.setAge(30);

ActionContext ac = ActionContext.getContext();
ValueStack vs = ac.getValueStack();
vs.push(u);

ac.put("user",u);
ac.put("msg","hello world");

name = "tom";

request.put("MyName", "tom1");
session.put("MyName", "tom2");
application.put("MyName","tom3");

return SUCCESS;
}

public static String test(){

return "static method";
}

public static String getVOMethod(){

return "GetValueActionTest";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public void setRequest(Map<String, Object> request) {
// TODO Auto-generated method stub
this.request = request;
}
public void setSession(Map<String, Object> session) {
// TODO Auto-generated method stub
this.session = session;
}
public void setApplication(Map<String, Object> application) {
// TODO Auto-generated method stub
this.application = application;
}
}






package com.briup.bean;


public class User {
private long id;
private String name;
private int age;

public String say(){

return "user say hello";
}

public static String test(){

return "static method in User";
}

public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}


19.struts2框架中的標籤


   <s:debug></s:debug>標籤:
      用來顯示action傳到頁面中的值(調試代碼時候常用到的)
   
   <s:property value=""/>標籤:
      取值並在頁面中輸出內容
   
   <s:if>     標籤:
   <s:elseif> 標籤:
   <s:else >  標籤:
   例子:
   注意:接收到的參數是字符串類型,需要先轉換成int類型再和數字比較
    <s:if test="@java.lang.Integer@parseInt(#parameters.score) >= 90">
    優秀
    </s:if>
    <s:elseif test="@java.lang.Integer@parseInt(#parameters.score) >= 80">
   
    </s:elseif>
    
    <s:elseif test="@java.lang.Integer@parseInt(#parameters.score) >= 70">
   
    </s:elseif>
    
    <s:elseif test="@java.lang.Integer@parseInt(#parameters.score) >= 60">
    及格
    </s:elseif>
   
    <s:else>
   
    </s:else>     




    <s:fielderror>標籤:
       瀏覽器發送請求到action,在運行期間,如果內部出現了什麼錯誤,將來跳轉之後能用這個標籤
       來顯示出錯誤的信息.


    <s:iterator>標籤:
    遍歷List集合:
    注意:每次遍歷接收到的集合 中的對象,都會默認放到ValueStack和ActionContext裏面。所以每次遍歷拿到
        一個對象後,我們可以從這兩個地方取值。
    從ValueStack取值:
  value屬性值是要遍歷的集合(可以從ValueStack和ActionContext裏面取到List集合),
  id屬性值,是表示每次遍歷到的對象用什麼名字接受。
   <s:iterator value="list" id="u">
     <s:property value="id"/>
     <s:property value="name"/>
     <s:property value="age"/>
 </s:iterator>
從ActionContext取值。
 <hr/>
  <s:iterator value="list" id="u">或者:<s:iterator value="#action.list" id="u">
  <s:property value="#u.id"/>
  <s:property value="#u.name"/>
  <s:property value="#u.age"/>
  
  </s:iterator>
    
      遍歷Map類型的集合:
注意:每次遍歷Map類型的集合拿到的時候一個鍵值對,這樣的鍵值對有倆個固定的屬性:key value,
分別拿到對應的key和value值.
        <s:iterator value="map" id="entry">
       //從ValueStack中取遍歷到的對象屬性值。
    <s:property value="key"/>  -->
    <s:property value="value.id"/>
    <s:property value="value.name"/>
    <s:property value="value.age"/>
    <br>
    </s:iterator>
    <br>
   
    <s:iterator value="map" id="entry">
       //從ActionContext中取遍歷到的對象屬性值。
    <s:property value="#entry.key"/>  -->
    <s:property value="#entry.value.id"/>
    <s:property value="#entry.value.name"/>
    <s:property value="#entry.value.age"/>
    <br>
    </s:iterator>






    <s:set>標籤:
       作用:把一個鍵值對(key-value)放到一個指定的範圍裏面,如果不指定,
       默認是放在ActionContext裏面(debug中可以看到)
       //name屬性表示值的名字(key)
       //value屬性表示值的內容(value)
       //value可以是一個固定的字符串,也可以用從其他範圍中取出的變量來表示
       //scope屬性表示要存放值的範圍.可以是request、session、application等,默認是ActionContext
       
       存值:
       例如
       <s:set name="MyName" value="'tom'"></s:set>
       <s:set name="MyName" value="user.name"></s:set>
       <s:set name="MyName" value="#entry.value.name"></s:set>
       <s:set name="MyName" value="'tom1'" scope="request"></s:set>


       取值:
       例如
       <s:property value="#MyName"/><br>
       <s:property value="#request.MyName"/><br>
 
       特殊的情況:
       1.存一個key的名字特殊的值
       存值:
       <s:set name="my.msg" value="'hello world'"></s:set>


       取值:
       //這樣是取不到的
       <s:property value="#my.msg"/>
       //這樣就可以取到了
       <s:property value="#attr['my.msg']"/>
       
       2.直接存放一個List/Map集合
       存值:  List/數組 
       <s:set name="myList" value="{'tom1','tom2','tom3'}"></s:set>


       取值:
       //獲得集合的長度
       <s:property value="#myList.size"/><br>
       //取到集合中某一個下標的值
       <s:property value="#myList[0]"/><br>
       
       存值:  Map類型集合
       //#除了可以表示從ActionContext中取值以爲,還能用來聲明Map類型集合
       <s:set name="myMap" value="#{'1':'tom1','2':'tom2','3':'tom3'}"></s:set>


       取值:
       //取得Map集合的長度
       <s:property value="#myMap.size"/><br>
       //取到所有Map集合中的key值
       <s:property value="#myMap.keys"/><br>
       //取到所有Map集合中的value值
       <s:property value="#myMap.values"/><br>
       //通過key值取到Map集合中的相對於的value值
       <s:property value="#myMap['2']"/><br>






    <<s:include>標籤
       作用:把另一個頁面直接包含在當前這個標籤所在位置.


       例如:
         <s:include value="index.jsp"></s:include>
同時還可以傳參數
<s:include value="index.jsp">
<s:param name="name" value="zhangsan"></s:param>
</s:include>


可以使用request.getParameter("name")來取得這個參數.
也可以使用ognl表達式取,但是比較麻煩.


    <s:form>標籤已經表單中的輸入框元素等:
    例如:
<s:form action="user/TagFormActionTest.action" method="post">
    <s:textfield name="username" label="用戶名"></s:textfield>
    <s:password name="password" label="密碼"></s:password>
    <!-- 
    把"男" 或者 "女"這個字符串傳到action中
    <s:radio list="{'男','女'}" name="gender" label="性別"></s:radio>
    下面是把"0"或者"1"傳給action
    -->
    <s:radio list="#{'0':'男','1':'女'}" name="gender" label="性別"></s:radio>
    <!-- 
    struts2標籤中的checkbox分倆種
    1.單個的checkbox
    2.一組checkbox(多個checkbox是一起的),多個的叫做checkboxlist
    -->
    <s:checkbox name="autoLogin" fieldValue="yes" label="一週內自動登錄"></s:checkbox>
   
    <!-- 
    value="{'2'}" 設置默認選擇的是籃球
   
    也可以這樣:  這個和上面單選框所表示的情況是一樣的
    list="{'足球','籃球','排球'}"
    -->
    <s:checkboxlist list="#{'1':'足球','2':'籃球','3':'排球'}" name="like" label="愛好"
value="{'2'}"></s:checkboxlist>
   
    <!-- 
    headerKey="-1"      
    headerValue="請選擇"
    這個倆個表示下拉列表最開始會多一個選項
    '-1':'請選擇'
   
    -->
    <s:select list="#{'1':'北京','2':'上海','3':'南京'}" name="city" label="城市" headerKey="-1" headerValue="請選擇"></s:select>
   
    <s:textarea cols="10" rows="5" name="dis" label="個人介紹"></s:textarea>
   
    <s:submit value="提交" method="execute"></s:submit>
    <s:submit value="註冊" method="register"></s:submit>
    <s:submit type="image" src="123.png"></s:submit>
    <s:submit type="image" src="3.png"></s:submit>
    </s:form>






    <s:a>標籤
       生成一個超鏈接
    <s:url>標籤
       聲明一個變量,這個變量的值是一個url,然後把這個變量默認的放到ActionContext裏面


    例如:
        <s:a href="http://www.baidu.com">百度1</s:a>
   
    <s:url value="http://www.baidu.com" var="myURL1"></s:url>
    <!-- myURL1是一個變量,在這裏面要用%{myURL1}來拿這個變量值 
    格式:%{ongl表達式}
    <s:url/>是會把這個變量放到ActionContext裏面的,
    同時我們不僅可以從ActionContext到這個變量值,
    還可以從ValueStack拿到。
    類似於<s:set/>標籤的效果
    -->
        <s:a href="%{myURL1}">百度2</s:a>
   
    <s:url value="/index.jsp" var="myURL2"></s:url>
    <s:a href="%{myURL2}">index.jsp</s:a>
   
    <s:url action="mytest" namespace="/user" var="myURL3"></s:url>
    <s:a href="%{myURL3}">mytest.action</s:a>
   
    <s:set name="myURL4" value="'http://www.baidu.com'"></s:set>
    <s:a href="%{#myURL4}">百度3</s:a>


  <s:text name="name">
  作用:使用國際化資源文件中的配置,name屬性的值,爲自己配置的資源文件的key值。就可以拿到資源文件中配置的
  值了。


20.struts2框架中的自定義轉換器(convertor)
   1.轉換器的作用
      幫我們把客戶端傳過來的數據,進行類型轉換的.
    2,轉化器如何工作:
    struts框架中已經寫好了很多轉換器,在我們傳值的時候,框架如果發現某一個值需要進行類型轉換
    ,而框架內部已經存在這樣一個相應的類型轉換器,那麼就會調用這個類型轉換器幫我們進行類型轉換。
    例如:用戶寫好了年齡24然後傳給action,本來這是一個字符串,但是傳到action中就會變成一個int類型的值。
    這個及時類型轉換器完成的工作。
同時我們還可以自定義轉換器,按照我們自己的要求,把一個值轉換成另外一種類型的值。
    3,如何去寫一個自定義轉換器
前提:頁面有一個輸入框,輸入框中輸入類似於這樣的數據:1:tom:20,提交數據之後
這個值會變成User對象
,然後放到了action裏面
1,寫一個轉換器類
繼承一個父類(抽象類):StrutsTypeConverter
例如:
package com.briup.web.converter;


import java.util.Map;


import org.apache.struts2.util.StrutsTypeConverter;


import com.briup.bean.User;


public class MyConverter extends StrutsTypeConverter {


@Override
public Object convertFromString(Map map, String[] str, Class c) {
System.out.println("in MyConverter"+str.length);

String s = str[0];
String[] strings = s.split(":");
long id = Long.parseLong(strings[0]);
String name = strings[1];
int age = Integer.parseInt(strings[2]);
User user = new User(id, name, age);

return user;
}


@Override
public String convertToString(Map map, Object o) {
return o.toString();
}


}


2,配置轉換器
   a,配置成局部的轉換器
     特點:只對某一個action起作用
    
    寫一個.properties資源文件
    1,文件的位置:
           和要使用的action放在同一個包下面
2,文件的名字:
xxx-conversion.properties
xxx值得是action的類名
注意:文件名字中的-conversion.properties是固定的,xxx是可變的
3,文件的內容:
例如:
user=com.briup.web.converter.MyConverter
表示的意思:當前數據提交到這個名字爲xxx的action裏面的時候,如果action中有一個名字叫
user的屬性,那麼這個屬性的值就要通過com.briup.web.converter.MyConverter  這個
轉換器轉換後在獲得。

   b,配置成全局的轉換器
               1,文件的位置:
           直接放到src下面
2,文件的名字:
xwork-conversion.properties


3,文件的內容:
例如:
com.briup.bean.User=com.briup.web.converter.MyConverter
表示的意思:當前數據提交到任何的action裏面的時候,如果action裏面有一個
類型爲com.briup.bean.User的屬性,
那麼這個屬性的值就要通過com.briup.web.converter.MyConverter  這個
轉換器轉換後在獲得。



21.struts框架中的數據驗證(validation)
    作用:客戶端提交的數據在到達action之前,struts框架可以幫我們去驗證一下這個數據是否符合我們的格式要求,
    如果符合要求,就讓action去接受這個數據,如果不符合,就會提示出錯誤,然後默認返回input字符串。


    1,我們需要使用xwork-2.1.2.jar這個jar包的類來進行數據的驗證
    2,需要寫一個xml文件
    作用:描述清楚action中的哪一個屬性需要被xwork-2.1.2.jar中的哪一個類進行驗證,並且定義出驗證不通過
    後返回的信息。
       a,文件的名字
       xxx-validation.xml
       xxx指的是數據提交到的action的類名,xxx後面是固定的寫法。
       b,文件的位置
         和這個名字爲xxx的action相同的包下面。
       
       c,文件的內容
這個xml文件內容是由一個dtd文件控制的。所以我們在文件中引入這個dtd,然後就可以自動提示生成要寫的
標籤了。
在這個xml文件中引入頭部聲明(引用dtd):
       在xwork-2.1.2.jar中,有很多dtd文件,我們可以打開一個叫xwork-validator-1.0.2.dtd文件,
       這個文件的註釋裏面就有我們需要的頭部聲明,就是這個標籤:<!DOCTYPE ...>
       把這個複雜到我們的xml文件中,做爲頭部聲明來引用需要的dtd文件,然後就可以自動提示了,
       如果不能提交,就像以前一樣,在MyEclipse中進行配置就可以了.


  一個配置的例子:


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE validators PUBLIC 
  "-//OpenSymphony Group//XWork Validator 1.0.2//EN" 
  "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
 
<validators>
<!-- 給當前action的哪一個屬性做驗證 -->
<field name="username">
<!-- 使用哪一個驗證器來驗證這個屬性值 -->
<!-- 驗證器的名字可以從xwork-2.1.2.jar包的default.xml中找到 -->
<!-- default.xml在com.opensymphony.xwork2.validator.validators包下面 -->
<field-validator type="requiredstring">
<!-- 如果這個驗證沒通過,返回的字符串信息 -->
<message>用戶名不爲空</message>
</field-validator>
</field>

<field name="password">
<field-validator type="requiredstring">
<message>密碼不能爲空</message>
</field-validator>

<!-- 同一個屬性可以使用多個驗證器驗證 -->
<field-validator type="stringlength">
   <!-- 可以給驗證器傳參數 -->
   <!-- 參數名字可以在驗證器類(API)中看到 -->
   <!-- 在default.xml文件中可以找這個驗證器是哪個類 -->
<param name="minLength">4</param>
<param name="maxLength">7</param>
<message>密碼長度必須是4-7個字符之間</message>
</field-validator>

</field>



</validators>
 
22.struts2框架的國際化配置(i18n)
作用:不同國家或者地區的人訪問我們這個同一個web項目,在頁面中顯示的文字等內容是不同的,
是和當前國家或者地區保持一致的。


internationalization




1.配置兩個資源文件
xxx_zh.properties
xxx_en.properties
例如:xxx隨便起的名字,比如:可以爲message
2.這兩個文件直接放在src下面。
比如:message_en.properties這個文件當中存放的是要顯示英文信息
message_zh.properties這個文件當中存放的是要顯示中文信息


例如:message_en.properties文件內容:
name=UserName
pwd=PassWord
注:name是key,UserName是是value值,name是在頁面中使用的,value是要最終顯示在頁面的內容,也
就是說,我們在頁面中通過key來拿到相對應的value來進行顯示。
name=用戶名
pwd=密碼
注:properties文件中是不能直接寫中文的。
要寫出這樣,JdK的命令native2ascii可以完成這個工作
name \u7528\u6237\u540D
        pwd=\u5BC6\u7801
4,在struts.xml文件中配置國際化的資源文件。
message爲資源文件的前綴:


<constant name="struts.custom.i18n.resources" value="message"></constant>


5,在頁面中使用struts2的標籤通過key拿到資源文件中的value值進行顯示。
    頁面中的代碼
    <s:text name="name"></s:text><input type="text" name="username"/><br>
 <s:text name="pwd"></s:text><input type="password" name="password">
 住: <s:text name="name">可以通過key拿到資源文件的value
 6.將來瀏覽器中到底是顯示中文還是英文,要看瀏覽器中默認優先使用的是哪一種語言來顯示當前頁面的,(我們
 自己可以設置這個語言)
















     
























發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章