Struts2處理結果的學習筆記

來源:互聯網
上載者:User

處理結果原理

在最開始的《Struts2學習之初見Struts2》這篇文章中,也簡單的說了說struts2中如何給要求者發送響應內容。這篇文章就對struts2中到底是如何處理響應結果進行詳細的總結。

通過前面的文章,我們知道Action只是Struts2控制器的一部分,所以它不能直接產生對瀏覽器的響應。Action只負責處理請求,負責產生響應的視圖組件,通常就是JSP頁面,而Action會為JSP頁面提供顯示的資料。當Action處理使用者請求結束後,將返回一個一般字元串,整個一般字元串就是一個邏輯視圖名。Struts2通過配置邏輯視圖名和物理視圖之間的映射關係,一旦系統收到Action返回的某個邏輯視圖名,系統就會把對應的物理視圖呈現給瀏覽者。

關於瀏覽者、控制器和視圖資源之間的時序圖如下:

如上圖所示,Action處理完使用者請求後,並未直接將請求轉寄給任何具體的視圖資源,而是返回一個代表邏輯視圖的一般字元串,Struts2架構收到這個邏輯視圖後,把請求轉寄到對應的視圖資源,視圖資源將處理結果呈現給使用者。

通過返回一個代表邏輯視圖的一般字元串,這樣的設計將Action類和Struts2架構進行瞭解耦、分離,提高了更好的代碼複用性。這就是在Struts2架構中處理結果的基本原理。

配置處理結果

控制器Action會返回一個代表邏輯視圖的一般字元串,我們需要在struts.xml中將邏輯視圖和物理視圖進行映射,Struts2在struts.xml檔案中使用<result .../>元素來配置結果,根據<result .../>元素所在位置的不同,Struts2提供了以下兩種結果:

局部結果:將<result .../>作為<action .../>元素的子項目配置
全域結果:將<result .../>作為<global-results .../>元素的子項目配置
配置<result .../>元素時通常需要指定如下兩個屬性:

name:該屬性指定所配置的邏輯視圖名
type:該屬性指定結果類型
下面就分別對如何配置局部結果和全域結果進行詳細的總結。

配置局部結果

前面的文章中,在struts.xml中都是這樣配置邏輯視圖和物理視圖之間的映射的:

<action name="login" class="com.jellythink.practise.LoginAction">
    <result name="default">/default.jsp</result>
</action>
上面的這種寫法使用了最簡單的形式,使用了很多預設的值,如果寫完整了,它應該是這個樣子的:

<action name="login" class="com.jellythink.practise.LoginAction">
    <result name="success" type="dispatcher">
        <param name="location">/success.jsp</param>
    </result>
</action>
這才是最繁瑣,最原始的寫法;既指定了需要映射的邏輯視圖名(success),也指定了結果類型(dispatcher),並使用子項目的形式來指定實際視圖資源。

對於上面使用<param .../>子項目配置結果的形式,其中<param .../>元素用於配置一個參數,與所有配置參數的地方相似,配置參數需要指定參數名和參數值。<param .../>元素配置的參數名由name屬性指定,此處的name屬性可以取如下兩個值:

location:該參數指定了該邏輯視圖對應的實際視圖資源
parse:該參數指定是否允許在實際視圖名字中使用OGNL運算式,預設值true。
由於不同的結果類型可以配置不同的參數,具體的請參見這裡。那麼為什麼這麼繁瑣的寫法可以簡化成那麼簡單的寫法呢?

在配置處理結果時,如果配置<result .../>元素時沒有指定location參數,系統將會把<result ...> ... </result>中間的字串當成實際視圖資源;如果沒有指定name屬性,則name屬性採用預設值:success;如果沒有指定type屬性,則採用Struts2的預設結果類型。基於此,我們就可以寫出最簡單的形式。

配置全域結果

如果將<result .../>元素配置在<global-results .../>元素中,那麼該<result .../>元素就配置了一個全域結果,全域結果將對所在包中的所有Action都有效。例如以下配置代碼:

<package name="lee" extends="struts-default" namespace="/Login" >
    <!--定義全域結果-->
    <global-results>
        <result name="error">/error.jsp</result>
    </global-results>
    <action name="login" class="com.jellythink.practise.LoginAction" />
</package>
雖然在<action .../>中沒有配置任何的<result .../>,由於配置了全域結果,所以這並不會妨礙系統的運行。

如果一個Action裡包含了與全域結果裡同名的結果,則Action裡的局部Result會覆蓋全域的Result。也就是說,當Action處理使用者請求結束後,首先會在本Action裡的局部變數裡搜尋邏輯視圖對應的結果,只有在Action裡的局部結果裡找不到邏輯視圖對應的結果,才會到全域結果裡搜尋。

在上面的總結的文章中,我們處理完成以後,都是轉到了JSP頁面,但是你需要知道,在Struts2中支援多種視圖技術,例如:JSP、Velocity和FreeMarker等。當一個Action處理使用者請求結束後,僅僅返回一個字串,這個字串是邏輯視圖名,但該邏輯視圖並未與任何的視圖技術及任何的視圖資源關聯——直到我們在struts.xml檔案中配置物理邏輯視圖資源。

控制器Action處理完之後,可能下一步想走到另一個控制器Action;或者一個JSP頁面;又或其它的什麼頁面,那麼是什麼決定了下一步將調用哪種“東西”來處理結果呢?

結果類型決定了Action處理結束後,下一步將調用哪種視圖資源來呈現處理結果。Struts2的結果類型要求實現com.opensymphony.xwork2.Result,這個結果是所有結果類型的通用介面。如果我們需要自己的結果類型(一般不需要),我們應該提供一個實現該介面的類,並在struts.xml檔案中配置該結果類型。先來看看Struts2架構支援哪些結果類型。

Struts2支援的結果類型

在Struts2中預設提供了一系列的結果類型,我們可以在struts-default.xml中看到以下配置代碼:

<result-types>
    <!--Action鏈式處理的結果類型-->
    <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>

    <!--用於與JSP整合的結果類型,作為預設的結果類型-->
    <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>

    <!--用於與FreeMarket整合的結果類型-->
    <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>

    <!--使用者控制特殊的HTTP行為的結果類型-->
    <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>

    <!--用於直接跳轉到其它URL的結果類型-->
    <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>

    <!--用於直接跳轉到其它Action的結果類型-->
    <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>

    <!--用於向瀏覽器返回一個InputStream的結果類型-->
    <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>

    <!--用於整合Velocity的結果類型-->
    <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>

    <!--用於整合XML/XSLT的結果類型-->
    <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>

    <!--用於顯示某個頁面原始代碼的結果類型-->
    <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />

    <!--將請求參數以form的形式提交到指定地點的結果類型-->
    <result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" />
</result-types>
關於上述結果類型更詳細的描述請參見這裡。雖然Struts2架構預設提供了這麼多種的結果類型,但是並不是每一種我們在開發中都會經常使用,接下來就對開發中經常使用的以下幾種結果類型進行總結。

dispatcher結果類型詳解

dispatcher結果類型是Struts2架構中預設的結果類型,dispatcher主要用於返回JSP,HTML等以頁面為基礎View視圖。在使用dispatcher時,唯一需要指定的是JSP或者HTML頁面的位置,這個位置將被用於定位返回的頁面;關於dispatcher的具體使用請參見這篇《Struts2學習之處理結果》中關於配置處理結果的總結。

redirect結果類型詳解

redirect和dispatcher結果類型是相對的,dispatcher結果類型是將請求forward(轉寄)到指定的URL(可以是JSP,也可以是Action);而redirect結果類型,則意味著將請求redirect(重新導向)到指定的視圖資源。

dispatcher和redirect的主要差別就是轉寄和重新導向的差別:重新導向會丟失所有的請求參數、請求屬性——當然也丟失了Action的處理結果。

使用redirect結果類型的效果是,系統將調用HttpServletResponse的sendRedirect(String)方法來重新導向指定視圖資源,這種重新導向的效果就是重新產生一個請求,因此所有的請求參數、請求屬性、Action執行個體和Action中封裝的屬性全部丟失。

在實際工作中,我們可以這樣來配置redirect結果類型:

<action name="login" class="com.jellythink.practise.LoginAction">
    <result name="error" type="redirect">/error.html</result>
</action>
如果在重新導向中需要攜帶參數,則只能使用以下這種方式:

<action name="login" class="com.jellythink.practise.LoginAction">
    <result name="error" type="redirect">/error.html?info=${info}</result>
</action>
redirectAction結果類型詳解

當需要讓一個Action處理結束後,直接將請求重新導向(是重新導向,而不是轉寄)到另一個Action時,我們應該使用redirectAction這種結果類型。

配置redirectAction結果類型時,可以指定如下兩個參數:

actionName:該參數指定重新導向的Action名
namespace:該參數指定需要重新導向的Action所在的命名空間
例如下面這段配置代碼所示:

<package name="Lee" extends="struts-default" namespace="/Login" >
    <action name="login" class="com.jellythink.practise.LoginAction">
        <result name="error" type="redirectAction">
            <param name="actionName">RedirectActionTest</param>
            <param name="namespace">/Test</param>
            <param name="userName">${userName}</param>
            <param name="password">${password}</param>
        </result>
    </action>
</package>
<package name="RedirectAction" extends="struts-default" namespace="/Test">
    <action name="RedirectActionTest" class="com.jellythink.practise.RedirectAction">
        <result name="error">/error.jsp</result>
    </action>
</package>
將請求重新導向到另一個Action時,也可以加上參數,就如上述配置代碼所示。

chain結果類型詳解

chain結果類型是將在一個Action處理完成以後,將請求再轉寄至另一個Action,一定要注意的是轉寄,轉寄就意味著請求參數都不會丟失。具體看如下配置代碼:

<package name="Lee" extends="struts-default" namespace="/Login" >
    <action name="login" class="com.jellythink.practise.LoginAction">
        <result name="error" type="chain">
            <param name="actionName">chainTest</param>
            <param name="namespace">/Test</param>
        </result>
    </action>
</package>
<package name="Chain" extends="struts-default" namespace="/Test">
    <action name="chainTest" class="com.jellythink.practise.ChainAction">
        <result name="error">/error.jsp</result>
    </action>
</package>

總結

關於Struts2架構的處理結果類型,這篇文章只是對幾個經常使用的結果類型進行了總結,還有一些也特別重要,比如stream;在後續的學習中,我們還會遇到其它的結果類型,到時候再進行總結。這篇文章就到此結束了,希望對大家的學習有協助。下一篇再見。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.