1. 程式人生 > >Struts2 學習 Struts2

Struts2 學習 Struts2

Struts2 

 

一、Struts2簡介

  1.概念:輕量級的MVC框架,主要解決了請求分發的問題,重心在控制層和表現層。低侵入性,與業務程式碼的耦合度很低。Struts2實現了MVC,並提供了一系列API,採用模式化方式簡化業務開發過程。

  2.與Servlet對比

    優點:業務程式碼解耦,提高開發效率

    缺點:執行效率偏低,需要使用反射、解析XML等技術手段,結構複雜

  3.不同框架實現MVC的方式

    Servlet:

    

    Spring:

    

    Struts2:

    

 

 

 

二、Struts2使用

   1.使用步驟

    匯入Struts2核心jar包

    在web.xml配置前端控制器filter

複製程式碼
<filter>
    <filter-name>Struts2</fileter-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.xml(格式可以參考核心包根路徑下的DTD檔案,struts-default.xml)

    編寫控制器Action

      - 方法是public的

      - 返回值為String型別(返回值與struts.xml->action->result的name屬性匹配,即根據此返回值找到對應result)

      - 引數列表為空

    建立JSP頁面

    配置struts.xml

複製程式碼
<struts>
   

  

      

    <!-- i18n:國際化,解決post亂碼問題 -->
    <constant name="struts.i18n.encoding" value="=UTF-8"></constant>
    <!-- 指定範文action的字尾名;如果不設定可以直接訪或者直接訪問路徑.action,兩個逗號表示可以為空,預設為action,如果設定則必須加.value(設定的值) -->
    <constant name="struts.action.extension" value="=action,,"></constant>
    <!-- 模式配置是false,如果改為true;
    表示開發模式 1、熱載入主配置(只對struts配置生效)不需要重啟即可生效
    2、可以提供更多的錯誤輸出,方便開發時的除錯 -->
    <constant name="struts.devMode" value="=false">

  </constant>

      

    <!--
        package:包,用於對Action進行封裝
        name:包名,根元素下可以有多個包,彼此不能重名
        extends:繼承,用於指定繼承的包,相當於將繼承包下的配置資訊複製到當前包
        namespace:名稱空間,用於規定Action的訪問路徑,必須“/”開頭    -->
    <package name="test01" namespace="/test01" extends="struts-default">
        <!--action:業務控制器,用於註冊業務控制器元件
            name:action名稱,用於規定Action的訪問路徑
            class:業務控制器元件,用於指定業務控制器對應的類
            method:方法,用於指定訪問當前action時要呼叫的方法
            *請求URL:http://ip:port/projectName/namespace/ActionName.action
        -->
        <action name="hello" class="test01.konrad.action.HelloAction" method="execute">
            <!--result:輸出元件,用於轉發、重定向、直接輸出
                name:名稱,一個action下可以有多個result,彼此不能重名
                預設值轉發,元素內設定轉發的頁面
            -->
            <result name="success">/hello.jsp</result>
        </action>
    </package>
</struts>
複製程式碼

 

 

 

三、引數傳遞

  1.Action從頁面取值  

    a)基本屬性注入(頁面,Action)

    

    b)域模型注入(頁面,Action)

    

  2.頁面從Action取值

    a)使用EL表示式

     

    b)OGNL

 

四、OGNL

   1.概念:Object Graph Navigation Language,是一門功能強大的表示式語言,類似於EL。Strut2預設採用OGNL表示式訪問Action的資料,實際上是通過ValueStack物件來訪問Action。

  2.用法:在Struts2中,OGNL表示式要結合Struts2標籤來訪問資料

    EL:${user.userName} <==> OGNL:<s:property value="user.userName">

    *a)訪問基本屬性  <s:property value="屬性名"/>

    *b)訪問實體物件  <s:property value="物件名.屬性名"/>

    c)訪問陣列/集合  <s:property value="someArray[1]"/> | <s:property value="someList[1]"/>

    d)訪問Map  <s:property value="someMap.key" />

    e)運算  <s:property value="'My name is' + name" />

    f)呼叫方法  <s:property value="name.toUpperCase()" />

    g)建立集合  <s:property value="{'a','b','c'}" /> ArrayList

    h)建立Map  <s:property value="#{'mm':'MM','nn':'NN'}" /> LinkedHashMap

      

五、ValueStack

  1.概念:是Struts2中,Action向頁面傳遞資料的媒介,封裝了Action的資料,並允許JSP通過OGNL來對其訪問

  2.原理

  

  3.訪問ValueStack

    a)通過<s:debug>觀察其結構

    b)輸出棧頂:<s:property />

    c)訪問Context物件:

      - OGNL表示式以"#"開頭

      - 以key來訪問context物件的值,即"#key"得到context中某屬性值

    d)迭代集合  

     

    

    e)按數字迭代

 

 

   4.ValueStack棧頂的變化

    - 預設情況下棧頂為Action

    - 迴圈過程中,棧頂為迴圈變數(集合迭代時,迴圈變數是集合中的物件,即棧頂為實體物件,可以以實體物件為root來寫OGNL表示式;數字迭代時,迴圈變數是數字,不能以數字為實體物件,需要通過var宣告變數名,以"#變數名"來引用,此情況下,是從context物件中取出值)

    - 迴圈結束後,棧頂變回Action

 

  5.EL表示式訪問ValueStack

    a)EL也是從ValueStack中取的值

    b)EL預設的取值範圍是page,request,session,application

    c)Struts2重寫的request的getAttribute方法,先試圖從原始request中取值,如果沒取到再從ValueStack中取值

 

六、Action基本原理

   1.6大核心元件

  

  FC:前端控制器,負責統一的分發請求

  Action:業務控制器,負責處理某一類業務

  ValueStack:Action與JSP資料互動的媒介

  Interceptor:攔截器,負責擴充套件Action,處理Action的共通事務

  Result:負責輸出的元件

  Tags:標籤,負責顯示資料、生成框體

  

  2.獲取Session的方式

    a)ActionContext

      - ActionContext.getContext().getSesion(),返回Map<String, Object>

    b)ServletActionContext

      - ServletActionContext.getRequest().getSession(),返回HttpSession

    c)SessionAware(推薦使用)

      - 讓Action實現SessionAware介面

      - 實現setSession(Map<String, Object> session)方法,Struts2會在例項化Action後呼叫方法,通過方法引數將Session物件注入進來

      - 定義成員變數,接收注入進來的Session物件

 

七、Result原理

   1.介紹:用於做輸出的元件,用於向頁面輸出一些內容,轉發、重定向可以理解為特殊方式的輸出。每一個Result實際上是一個類,這些類都實現了共同的介面Result。Struts2預置了10種類型的Result,定義在strtus-default.xml

  2.Result型別

    a)dispatcher:用於轉發的result,可以將請求轉發給JSP,這種型別的Result對應的類為ServletDispacherResult,通過default="true"指定該Result為Struts2預設的Result型別。

    b)stream:用於向頁面輸出二進位制資料,此種類型的Result可以將二進位制資料輸出到請求發起端,對應類為StreamResult

<result name="success" type="stream">
  <!--codeStream 為定義在Action的輸入流InputStream --> <param name="inputName">codeStream</param> </result>

 

    c)redirectAction:用於將請求重定向給另外一個Action,對應類為ServletActionRedirectResult

複製程式碼
<result name="login" type="redirectAction">
    <!--若重定向的Action與當前Action在同一個namespace下,可以省略namespace-->
    <param name="namespace">
    /名稱空間
    </param>
    <param name="actionName">
    action名
    </param>
</result>
複製程式碼

 

    d)json:用於向頁面輸出json格式的資料,可以將json字串輸出到請求發起端。對應類為JSONResult

複製程式碼
<result name="success" type="json">
    <!--輸出一個Action屬性
    指定屬性為基本型別,則直接返回該屬性值
    如果指定屬性為實體物件,則返回格式{"code":"as1","name":"hk"}
    -->
    <param name="root">屬性名</param>
    <!--輸出多個Action屬性-->
    <param name="includeProperties">屬性名1,屬性名2...</param>
    <!--輸出所有屬性,不需要param標籤-->
   
</result>
複製程式碼

 

    json需要導包,修改package繼承關係為json-default

八、UI標籤

  1.表單  <s:form action="" method="" theme="simple" ></s:form>

  2.文字框  <s:textfield name="userName" />

  3.布林框  <s:checkbox name="marry" />

  4.單選框  <s:radio name="sex" list="#{'M':'男','F':'女'}"/> 靜態初始化

        <s:radio name="favoriteCities" list="cities" listKey="cityCode" listValue="cityName" /> 動態初始化

  5.多選框  <s:checkboxlist name="travelCities" list="#{'01':'北京','02':'上海','03':'廣州'}" /> 靜態初始化

        <s:checkboxlist name="travelCities" list="cities" listKey="cityCode" listValue="cityName" /> 動態初始化

  6.下拉選  <s:select name="home" list="#{'01':'北京','02':'上海','03':'廣州'}" /> 靜態初始化

        <s:select name="home" list="cities" listKey="cityCode" listValue="cityName" /> 動態初始化

 

 

九、攔截器

  1.用途:攔截器適合封裝一些通用處理,便於重複利用。例如請求引數傳遞給Action屬性,日誌的記錄,許可權檢查,事務處理等。攔截器是通過配置方式呼叫,因此使用方法比較靈活,便於維護和擴充套件。

  2.使用步驟

    建立攔截器元件(建立一個類,實現Interceptor介面,並實現intercept方法;也可以繼承MethodFilterInterceptor,這種方式可以使action中某個方法不進行攔截)

public String intercept(ActionInvocation invocation){
   //攔截器--前部分處理
   invocation.invoke();
   //攔截器--後續處理      
}

 

 

 

    註冊攔截器

<package>
    <interceptors>
        <interceptor name="別名" class="實現類"/>
        <!--其他攔截器-->
    </interceptors>
</package>

 

 

 

    引用攔截器(哪個Action希望被攔截器擴充套件,需要在此action配置下,引用攔截器)

複製程式碼
<action>
   <!--手動的使用一次系統預設的攔截器-->
   <interceptor-ref name="defaultStack"/> <interceptor-ref name="攔截器別名"/> <!--可以寫多個-->
   <!--可以使用excludeMethods引數屬性,設定不過濾的方法--> </action>
複製程式碼

 

 

 

  

  3.攔截器棧

<interceptor-stack name="myStack">
    <interceptor-ref name="攔截器別名1"/>
    <interceptor-ref name="攔截器別名2"/>
</interceptor-stack>

 

 

 

 

 

  4.FileUpload攔截器

    a)原理:首先FileUpload攔截器將表單中提交的檔案,以臨時檔案的形式儲存到伺服器臨時路徑下。之後FileUpload攔截器將該臨時檔案物件注入給Action,Action自主處理該臨時檔案。最後FileUpload攔截器刪除臨時檔案。

    b)使用步驟

      導包 commons-io.jar

      Action:定義File型別屬性(如some),接受攔截器注入的臨時檔案物件。若想要獲取原始檔名,要定義String型別屬性,屬性名為File型別屬性+FileName(如someFileName)

      表單設定:method="post", enctype="multipart/form-data"

    c)設定限制(Struts2檔案上傳預設最大值為2097152B,即2M)

      在struts.xml中重置預設限制值  <constant name="struts.multipart.maxSize" value="5000000" />

一、Struts2簡介

  1.概念:輕量級的MVC框架,主要解決了請求分發的問題,重心在控制層和表現層。低侵入性,與業務程式碼的耦合度很低。Struts2實現了MVC,並提供了一系列API,採用模式化方式簡化業務開發過程。

  2.與Servlet對比

    優點:業務程式碼解耦,提高開發效率

    缺點:執行效率偏低,需要使用反射、解析XML等技術手段,結構複雜

  3.不同框架實現MVC的方式

    Servlet:

    

    Spring:

    

    Struts2:

    

 

 

 

二、Struts2使用

   1.使用步驟

    匯入Struts2核心jar包

    在web.xml配置前端控制器filter

複製程式碼
<filter>
    <filter-name>Struts2</fileter-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.xml(格式可以參考核心包根路徑下的DTD檔案,struts-default.xml)

    編寫控制器Action

      - 方法是public的

      - 返回值為String型別(返回值與struts.xml->action->result的name屬性匹配,即根據此返回值找到對應result)

      - 引數列表為空

    建立JSP頁面

    配置struts.xml

複製程式碼
<struts>
   

  

      

    <!-- i18n:國際化,解決post亂碼問題 -->
    <constant name="struts.i18n.encoding" value="=UTF-8"></constant>
    <!-- 指定範文action的字尾名;如果不設定可以直接訪或者直接訪問路徑.action,兩個逗號表示可以為空,預設為action,如果設定則必須加.value(設定的值) -->
    <constant name="struts.action.extension" value="=action,,"></constant>
    <!-- 模式配置是false,如果改為true;
    表示開發模式 1、熱載入主配置(只對struts配置生效)不需要重啟即可生效
    2、可以提供更多的錯誤輸出,方便開發時的除錯 -->
    <constant name="struts.devMode" value="=false">

  </constant>

      

    <!--
        package:包,用於對Action進行封裝
        name:包名,根元素下可以有多個包,彼此不能重名
        extends:繼承,用於指定繼承的包,相當於將繼承包下的配置資訊複製到當前包
        namespace:名稱空間,用於規定Action的訪問路徑,必須“/”開頭    -->
    <package name="test01" namespace="/test01" extends="struts-default">
        <!--action:業務控制器,用於註冊業務控制器元件
            name:action名稱,用於規定Action的訪問路徑
            class:業務控制器元件,用於指定業務控制器對應的類
            method:方法,用於指定訪問當前action時要呼叫的方法
            *請求URL:http://ip:port/projectName/namespace/ActionName.action
        -->
        <action name="hello" class="test01.konrad.action.HelloAction" method="execute">
            <!--result:輸出元件,用於轉發、重定向、直接輸出
                name:名稱,一個action下可以有多個result,彼此不能重名
                預設值轉發,元素內設定轉發的頁面
            -->
            <result name="success">/hello.jsp</result>
        </action>
    </package>
</struts>
複製程式碼

 

 

 

三、引數傳遞

  1.Action從頁面取值  

    a)基本屬性注入(頁面,Action)

    

    b)域模型注入(頁面,Action)

    

  2.頁面從Action取值

    a)使用EL表示式

     

    b)OGNL

 

四、OGNL

   1.概念:Object Graph Navigation Language,是一門功能強大的表示式語言,類似於EL。Strut2預設採用OGNL表示式訪問Action的資料,實際上是通過ValueStack物件來訪問Action。

  2.用法:在Struts2中,OGNL表示式要結合Struts2標籤來訪問資料

    EL:${user.userName} <==> OGNL:<s:property value="user.userName">

    *a)訪問基本屬性  <s:property value="屬性名"/>

    *b)訪問實體物件  <s:property value="物件名.屬性名"/>

    c)訪問陣列/集合  <s:property value="someArray[1]"/> | <s:property value="someList[1]"/>

    d)訪問Map  <s:property value="someMap.key" />

    e)運算  <s:property value="'My name is' + name" />

    f)呼叫方法  <s:property value="name.toUpperCase()" />

    g)建立集合  <s:property value="{'a','b','c'}" /> ArrayList

    h)建立Map  <s:property value="#{'mm':'MM','nn':'NN'}" /> LinkedHashMap

      

五、ValueStack

  1.概念:是Struts2中,Action向頁面傳遞資料的媒介,封裝了Action的資料,並允許JSP通過OGNL來對其訪問

  2.原理

  

  3.訪問ValueStack

    a)通過<s:debug>觀察其結構

    b)輸出棧頂:<s:property />

    c)訪問Context物件:

      - OGNL表示式以"#"開頭

      - 以key來訪問context物件的值,即"#key"得到context中某屬性值

    d)迭代集合  

     

    

    e)按數字迭代

 

 

   4.ValueStack棧頂的變化

    - 預設情況下棧頂為Action

    - 迴圈過程中,棧頂為迴圈變數(集合迭代時,迴圈變數是集合中的物件,即棧頂為實體物件,可以以實體物件為root來寫OGNL表示式;數字迭代時,迴圈變數是數字,不能以數字為實體物件,需要通過var宣告變數名,以"#變數名"來引用,此情況下,是從context物件中取出值)

    - 迴圈結束後,棧頂變回Action

 

  5.EL表示式訪問ValueStack

    a)EL也是從ValueStack中取的值

    b)EL預設的取值範圍是page,request,session,application

    c)Struts2重寫的request的getAttribute方法,先試圖從原始request中取值,如果沒取到再從ValueStack中取值

 

六、Action基本原理

   1.6大核心元件

  

  FC:前端控制器,負責統一的分發請求

  Action:業務控制器,負責處理某一類業務

  ValueStack:Action與JSP資料互動的媒介

  Interceptor:攔截器,負責擴充套件Action,處理Action的共通事務

  Result:負責輸出的元件

  Tags:標籤,負責顯示資料、生成框體

  

  2.獲取Session的方式

    a)ActionContext

      - ActionContext.getContext().getSesion(),返回Map<String, Object>

    b)ServletActionContext

      - ServletActionContext.getRequest().getSession(),返回HttpSession

    c)SessionAware(推薦使用)

      - 讓Action實現SessionAware介面

      - 實現setSession(Map<String, Object> session)方法,Struts2會在例項化Action後呼叫方法,通過方法引數將Session物件注入進來

      - 定義成員變數,接收注入進來的Session物件

 

七、Result原理

   1.介紹:用於做輸出的元件,用於向頁面輸出一些內容,轉發、重定向可以理解為特殊方式的輸出。每一個Result實際上是一個類,這些類都實現了共同的介面Result。Struts2預置了10種類型的Result,定義在strtus-default.xml

  2.Result型別

    a)dispatcher:用於轉發的result,可以將請求轉發給JSP,這種型別的Result對應的類為ServletDispacherResult,通過default="true"指定該Result為Struts2預設的Result型別。

    b)stream:用於向頁面輸出二進位制資料,此種類型的Result可以將二進位制資料輸出到請求發起端,對應類為StreamResult

<result name="success" type="stream">
  <!--codeStream 為定義在Action的輸入流InputStream --> <param name="inputName">codeStream</param> </result>

 

    c)redirectAction:用於將請求重定向給另外一個Action,對應類為ServletActionRedirectResult

複製程式碼
<result name="login" type="redirectAction">
    <!--若重定向的Action與當前Action在同一個namespace下,可以省略namespace-->
    <param name="namespace">
    /名稱空間
    </param>
    <param name="actionName">
    action名
    </param>
</result>
複製程式碼

 

    d)json:用於向頁面輸出json格式的資料,可以將json字串輸出到請求發起端。對應類為JSONResult

複製程式碼
<result name="success" type="json">
    <!--輸出一個Action屬性
    指定屬性為基本型別,則直接返回該屬性值
    如果指定屬性為實體物件,則返回格式{"code":"as1","name":"hk"}
    -->
    <param name="root">屬性名</param>
    <!--輸出多個Action屬性-->
    <param name="includeProperties">屬性名1,屬性名2...</param>
    <!--輸出所有屬性,不需要param標籤-->
   
</result>
複製程式碼

 

    json需要導包,修改package繼承關係為json-default

八、UI標籤

  1.表單  <s:form action="" method="" theme="simple" ></s:form>

  2.文字框  <s:textfield name="userName" />

  3.布林框  <s:checkbox name="marry" />

  4.單選框  <s:radio name="sex" list="#{'M':'男','F':'女'}"/> 靜態初始化

        <s:radio name="favoriteCities" list="cities" listKey="cityCode" listValue="cityName" /> 動態初始化

  5.多選框  <s:checkboxlist name="travelCities" list="#{'01':'北京','02':'上海','03':'廣州'}" /> 靜態初始化

        <s:checkboxlist name="travelCities" list="cities" listKey="cityCode" listValue="cityName" /> 動態初始化

  6.下拉選  <s:select name="home" list="#{'01':'北京','02':'上海','03':'廣州'}" /> 靜態初始化

        <s:select name="home" list="cities" listKey="cityCode" listValue="cityName" /> 動態初始化

 

 

九、攔截器

  1.用途:攔截器適合封裝一些通用處理,便於重複利用。例如請求引數傳遞給Action屬性,日誌的記錄,許可權檢查,事務處理等。攔截器是通過配置方式呼叫,因此使用方法比較靈活,便於維護和擴充套件。

  2.使用步驟

    建立攔截器元件(建立一個類,實現Interceptor介面,並實現intercept方法;也可以繼承MethodFilterInterceptor,這種方式可以使action中某個方法不進行攔截)

public String intercept(ActionInvocation invocation){
   //攔截器--前部分處理
   invocation.invoke();
   //攔截器--後續處理      
}

 

 

 

    註冊攔截器

<package>
    <interceptors>
        <interceptor name="別名" class="實現類"/>
        <!--其他攔截器-->
    </interceptors>
</package>

 

 

 

    引用攔截器(哪個Action希望被攔截器擴充套件,需要在此action配置下,引用攔截器)

複製程式碼
<action>
   <!--手動的使用一次系統預設的攔截器-->
   <interceptor-ref name="defaultStack"/> <interceptor-ref name="攔截器別名"/> <!--可以寫多個-->
   <!--可以使用excludeMethods引數屬性,設定不過濾的方法--> </action>
複製程式碼

 

 

 

  

  3.攔截器棧

<interceptor-stack name="myStack">
    <interceptor-ref name="攔截器別名1"/>
    <interceptor-ref name="攔截器別名2"/>
</interceptor-stack>

 

 

 

 

 

  4.FileUpload攔截器

    a)原理:首先FileUpload攔截器將表單中提交的檔案,以臨時檔案的形式儲存到伺服器臨時路徑下。之後FileUpload攔截器將該臨時檔案物件注入給Action,Action自主處理該臨時檔案。最後FileUpload攔截器刪除臨時檔案。

    b)使用步驟

      導包 commons-io.jar

      Action:定義File型別屬性(如some),接受攔截器注入的臨時檔案物件。若想要獲取原始檔名,要定義String型別屬性,屬性名為File型別屬性+FileName(如someFileName)

      表單設定:method="post", enctype="multipart/form-data"

    c)設定限制(Struts2檔案上傳預設最大值為2097152B,即2M)

      在struts.xml中重置預設限制值  <constant name="struts.multipart.maxSize" value="5000000" />