Struts2系統學習(3)Action深入

3. Action深入

3.1 Action類

  在Struts2中,一個Action類代表一次請求或調用,每個請求的動作都對應於一個相應的Action類,一個Action類是一個獨立的工作單元。
  也就是說,用戶的每次請求,都會轉到一個相應的Action類裏面,由這個Action類來進行處理,因此說一個Action類代表了用戶的一次請求或調用。
  並且每個用戶的請求都會創建獨立的action對象,因此action是線程安全的。

3.2 Action名稱的搜索順序

  案例一:假設請求路徑的URL爲:http://server/app/path1/path2/path3/test.action

  1. 首先尋找namespace爲/path1/path2/path3的package,如果不存在這個package則執行步驟3;如果存在這個package,則在這個package中尋找名字爲test的action,當在該package下尋找不到action時就會直接跑到默認namaspace的package裏面去尋找action(默認的命名空間爲空字符串“” ),如果在默認namaspace的package裏面還尋找不到該action,頁面提示找不到action。
  2. 尋找namespace爲/path1/path2的package,如果不存在這個package,則轉至步驟4;如果存在這個package,則在這個package中尋找名字爲test的action,當在該package中尋找不到action時就會直接跑到默認namaspace的package裏面去找名字爲test的action,在默認namaspace的package裏面還尋找不到該action,頁面提示找不到action。
  3. 尋找namespace爲/path1的package,如果不存在這個package則執行步驟5;如果存在這個package,則在這個package中尋找名字爲test的action,當在該package中尋找不到action時就會直接跑到默認namaspace的package裏面去找名字爲test的action,在默認namaspace的package裏面還尋找不到該action,頁面提示找不到action。
  4. 尋找namespace爲/的package,如果存在這個package,則在這個package中尋找名字爲test的action,當在package中尋找不到action或者不存在這個package時,都會去默認namaspace的package裏面尋找action,如果還是找不到,頁面提示找不到action。

    案例二:
    如下配置:
<struts>
    <package name="day01" namespace="/day01" extends="struts-default">
        <action name="helloworld" class="com.markliu.test.HelloWorldAction" method="execute">
            <result name="success">/WEB-INF/pages/sayhello.jsp</result>
        </action>
    </package>
</struts>

  可通過 http://ip:port/app/day01/helloworld.action訪問該action,也可以通過:http://ip:port/app/day01/kjhsd/asd/helloworld.action訪問。
  案例三:
如下配置:

<package name="day01" namespace="/day01" extends="struts-default">
</package>
<package name="day02" namespace="" extends="struts-default">
    <action name="helloworld" class="com.markliu.test.HelloWorldAction" method="execute">
        <result name="success">/WEB-INF/pages/sayhello.jsp</result>
    </action>
</package>

  可通過 http://ip:port/app/day01/kjhsd/asd/helloworld.action訪問該action。在/day01命名空間下沒有找到helloworld.action,則直接到默認namaspace的package裏面尋找action。

3.3 Action配置中的各項默認值

    <package name="day01-2" namespace="/day01" extends="struts-default">
        <action name="helloworld">
            <result>/WEB-INF/pages/sayhello.jsp</result>
        </action>
    </package>

(1)如果沒有爲action指定class,默認com.opensymphony.xwork2.ActionSupport。
(2)如果沒有爲action指定method,默認執行action中的execute() 方法。
(3)如果沒有指定result的name屬性,默認值爲success。
  查看ActionSupport類,會發現默認存在execute方法,且返回success:

public String execute() throws Exception {
    // public static final String SUCCESS = "success";
    return SUCCESS;
}

3.4 Action中result的各種轉發類型

  result配置類似於struts1中的forward,但struts2中提供了多種結果類型,常用的類型有: dispatcher(默認值:內部轉發)、 redirect 、 redirectAction 、 plainText。

3.4.1 dispatcher(default)轉發類型

默認爲服務器內部請求轉發。

<action name="helloworld" class="com.markliu.test.HelloWorldAction">
    <result name="success">/WEB-INF/page/hello.jsp</result>
</action>

3.4.2 redirect 轉發類型

  注意請求重定向的視圖不能放在/WEB-INF/目錄下。
  在result中還可以使用${屬性名}表達式(OGNL表達式)訪問action中的屬性
,表達式裏的屬性名對應action中的屬性(getter)。如下:

<result type="redirect">/view.jsp?username=${username}</result>

  注意:如果username爲中文,會出現中文亂碼,需要進行URLEncode進行編碼。

  (1)在action中爲username中文編碼

    public String execute() throws Exception {
        this.username = URLEncoder.encode("Sunny中文", "UTF-8");
        return SUCCESS;
    }

  (2)瀏覽器訪問該action,地址欄顯示編碼後的地址:
http://localhost:8080/Struts2/pages/day02/useredit.jsp?username=Sunny%E5%88%98%E5%BA%86

  (3)在顯示的視圖頁面中獲取請求參數,並進行解碼:

${param.username }

  由於在jsp的頭部設置了編碼的格式,所以會自動按照UTF-8解碼。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

3.4.3 redirectAction轉發類型

如果重定向的action中同一個包下:

<result type="redirectAction">重定向action名稱</result>

如果重定向的action在別的命名空間下:

<result type="redirectAction">
    <param name="actionName">重定向action名稱</param>
    <param name="namespace">重定向action所在包名</param>
</result>

在struts2-core-2.3.24.1.jar包下面的struts-default.xml文件中,對struts-default包定義中存在下面對result-type結果視圖類型的定義:

<result-types>
    <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
    <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
    <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
    <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
    <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
    <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
    <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
    <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
    <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
    <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
    <result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" />
</result-types>

  其中就包含dispatcher,redirect,redirectAction,plainText四種result轉發類型的定義,分別對應一個java類。打開redirectAction對應的java類ServletActionRedirectResult:
存在如下屬性:

protected String actionName;
protected String namespace;
protected String method;

  所以設置:

<param name="actionName">重定向action名稱</param>
<param name="namespace">/重定向action包名</param>
<param name="method">execute</param>

  實際就是爲ServletActionRedirectResult對象注入屬性值:setNamespace和setActionName

3.4.4 plainText轉發類型

  plainText:顯示原始文件內容,例如:當我們需要原樣顯示jsp文件源代碼的時候,我們可以使用此類型。
按照上面的方法找到定義plainText的類:PlainTextResult,需要設置兩個屬性:
  ·location (default): 作爲plain text顯示的jsp、html等文件的路徑
  ·charSet (optional): 設置響應的編碼格式(eg. Content-Type=text/plain; charset=UTF-8) ,並且設置讀取該文件所採用的格式。如果不設置 charSet ,Tomcat讀取該文件的時候採用系統默認的編碼格式(eg.GBK),會出現中文亂碼!

 <action name="displayJspRawContent" >
   <result type="plainText">/myJspFile.jsp</result>
 </action>

  一般採用下面的方式:

 <action name="displayJspRawContent" >
   <result type="plainText">
      <param name="location">/myJspFile.jsp</param>
      <param name="charSet">UTF-8</param>
   </result>
 </action>

3.5 多個Action共享一個視圖 — 全局result配置

  當多個action中都使用到了相同視圖,這時我們應該把result定義爲全局視圖。struts1中提供了全局forward,struts2中也提供了相似功能:
(1) 當全局視圖位於同一個package下:

<package name="day02" namespace="/day02" extends="struts-default">    
<!-- 全局視圖 -->
<global-results>
<result name="global-message">/WEB-INF/pages/global/message.jsp</result>
</global-results>       
<action name="globalresults" class="com.markliu.UserEditAction" method="global">
</action>
</package>

  其中UserEditAction的global方法返回global-message
(2) 當全局視圖位於不同的package下:
應用package的繼承功能實現:

<package name="base" extends="struts-default">
    <global-results>
        <result name="global-message">/WEB-INF/pages/global/message.jsp</result>
    </global-results>
</package>
<package name="day02" namespace="/day02" extends="base">
<action name="global-results" class="com.markliu.UserEditAction" method="global">
</action>
</package>

  當訪問/day02/global-results時,gloal函數返回global-message,當前包中沒有找到對應的result,則去父包base中找。
3.6 爲Action的屬性注入值
  Struts2爲Action中的屬性提供了依賴注入功能,在struts2的配置文件中,我們可以很方便地爲Action中的屬性注入值。注意:屬性必須提供setter方法。

package com.markliu.test;
import java.net.URLEncoder;
import com.opensymphony.xwork2.Action;
public class UserEditAction implements Action {
    private int id;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    @Override
    public String execute() throws Exception {
        return SUCCESS;
    }
}
<action name="action-inject" class="com.markliu.test.UserEditAction" >
    <param name="id">12</param>
    <result name="success">/WEB-INF/pages/day02/inject.jsp</result>
</action>

  上面通過節點爲action的id屬性注入12。

3.7 指定需要Struts 2處理的請求後綴

  前面我們都是默認使用.action後綴訪問Action。其實默認後綴是可以通過常量”struts.action.extension“進行修改的,例如:我們可以配置Struts 2只處理以.do爲後綴的請求路徑:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <constant name="struts.action.extension" value="do"/>
</struts>

  如果用戶需要指定多個請求後綴,則多個後綴之間以英文逗號(,)隔開。如:

<constant name="struts.action.extension" value="do,go"/>

  注意:修改之後,訪問的.do或.go不能省略!

3.8 細說常量定義

3.8.1 常量的配置方法和順序

  常量可以在struts.xml或struts.properties中配置,建議在struts.xml中配置,兩種配置方式如下:
在struts.xml文件中配置常量

<struts>
    <constant name="struts.action.extension" value="do"/>
</struts>

  在struts.properties中配置常量

struts.action.extension=do

  因爲常量可以在多個配置文件中進行定義,struts2加載常量的順序:
struts-default.xml
struts-plugin.xml
struts.xml
struts.properties
web.xml

  如果在多個文件中配置了同一個常量,則後一個文件中配置的常量值會覆蓋前面文件中配置的常量值。

3.8.2 常用的常量介紹

    <!-- 指定默認編碼集,作用於HttpServletRequest的setCharacterEncoding方法 和freemarker 、velocity的輸出,i18n表示國際化 -->
    <constant name="struts.i18n.encoding" value="UTF-8"/>
    <!-- 該屬性指定需要Struts 2處理的請求後綴,該屬性的默認值是action,即所有匹配*.action的請求都由Struts2處理。如果用戶需要指定多個請求後綴,則多個後綴之間以英文逗號(,)隔開。 -->
    <constant name="struts.action.extension" value="do"/>
    <!-- 設置瀏覽器是否緩存靜態內容,默認值爲true(生產環境下使用),開發階段最好關閉 -->
    <constant name="struts.serve.static.browserCache" value="false"/>
    <!-- 當struts的配置文件修改後,系統是否自動重新加載該文件,默認值爲false(生產環境下使用),開發階段最好打開 -->
    <constant name="struts.configuration.xml.reload" value="true"/>
    <!-- 開發模式下使用,這樣可以打印出更詳細的錯誤信息 -->
    <constant name="struts.devMode" value="true" />
     <!-- 默認的視圖主題 -->
    <constant name="struts.ui.theme" value="simple" />
    <!–spring集成時,指定由spring負責action對象的創建 -->
    <constant name="struts.objectFactory" value="spring" />
    <!–該屬性設置Struts 2是否支持動態方法調用,該屬性的默認值是true。如果需要關閉動態方法調用,則可設置該屬性爲false-->
    <constant name="struts.enable.DynamicMethodInvocation" value="false"/>
    <!--上傳文件的大小限制-->
    <constant name="struts.multipart.maxSize" value=“10701096"/>

轉載請註明出處:http://blog.csdn.net/mark_lq/article/details/49801945

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