首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Struts 2 <result> 標簽深度解析:多結果類型、鏈式調用與動態映射

     編輯:Java 相關知識

前言

<result> 是 Struts 2 將 Action 邏輯結果映射到視圖的核心配置。本文系統講解分發器、重定向、FreeMarker、JSON、鏈式結果等類型,以及動態參數、全局結果、異常映射等進階用法。

一、結果類型全景

類型類名/別名適用場景關鍵參數
分發器(默認)dispatcher / ServletDispatcherResult服務端轉發到 JSP/HTMLlocation、parse=true
重定向redirect / ServletRedirectResult客戶端跳轉,URL 變化location、parse=true、anchor
重定向動作redirectAction重定向到另一個 ActionactionName、namespace、suppressEmptyParameters
鏈式調用chain同一請求內調用另一 Action,共享狀態actionName、namespace、method
FreeMarkerfreemarker模板引擎渲染location(模板路徑)
Velocityvelocity模板引擎渲染location
JSONjson (struts2-json-plugin)REST API 返回數據root、includeProperties、excludeProperties
Streamstream文件下載、圖片輸出、二進制流inputName、contentType、contentLength、bufferSize
XSLTxsltXML 轉換location(XSL 文件)、matchingPattern
Tilestiles頁面佈局框架整合location(Tiles 定義名)
JFreeChartjasper報表導出location(.jrxml)、dataSource、format

二、核心配置語法

1. 簡寫形式(僅 location)

<action name="hello" class="com.example.HelloAction">
    <result name="success">/WEB-INF/jsp/hello.jsp</result>
</action>

2. 完整形式(指定 type + 參數)

<action name="download" class="com.example.DownloadAction">
    <result name="success" type="stream">
        <param name="inputName">inputStream</param>
        <param name="contentType">application/octet-stream</param>
        <param name="contentDisposition">attachment;filename="${filename}"</param>
        <param name="bufferSize">4096</param>
    </result>
</action>

3. 多結果映射

<action name="login" class="com.example.LoginAction" method="execute">
    <result name="success" type="redirectAction">
        <param name="actionName">dashboard</param>
    </result>
    <result name="input">/login.jsp</result> <!-- 驗證失敗返回表單 -->
    <result name="locked">/account_locked.jsp</result>
    <result name="error" type="json">
        <param name="root">errorMsg</param>
    </result>
</action>

三、進階特性詳解

1. 參數解析(parse)與 OGNL 表達式

  • parse=true(默認):location 中的 ${...} 會被 OGNL 解析
  • 動態構建 URL:<param name="location">/user/${userId}/profile</param>
  • 關閉解析:<param name="parse">false</param>(靜態路徑提升性能)

2. 全局結果(<global-results>)

<package name="default" extends="struts-default">
    <global-results>
        <result name="login" type="redirect">/login.jsp</result>
        <result name="error">/common/error.jsp</result>
        <result name="noPermission">/common/403.jsp</result>
    </global-results>
    
    <global-exception-mappings>
        <exception-mapping exception="java.sql.SQLException" result="error"/>
        <exception-mapping exception="com.example.BizException" result="error"/>
    </global-exception-mappings>
    ...
</package>

所有 Action 共享,減少重複配置。

3. 重定向動作(redirectAction)最佳實踐

<action name="saveUser" class="com.example.UserAction" method="save">
    <result name="success" type="redirectAction">
        <param name="actionName">userList</param>
        <param name="namespace">/admin</param>
        <param name="suppressEmptyParameters">true</param> <!-- 避免攜帶空參數 -->
    </result>
    <result name="input">/user_form.jsp</result>
</action>

等效於 return "redirectAction:userList?namespace=/admin"(代碼中)。

4. 鏈式調用(chain)vs 重定向

特性chainredirectAction
請求同一 HTTP 請求新 HTTP 請求(302)
Action 實例新建目標 Action新建目標 Action
ValueStack共享(源 Action 數據可用)不共享(新請求新棧)
URL不變變為目標 Action URL
適用場景多步驟向導、預處理後轉發POST-Redirect-GET 模式、跨命名空間

5. JSON 結果配置(struts2-json-plugin)

<action name="api/users" class="com.example.ApiUserAction">
    <result name="success" type="json">
        <param name="root">userList</param> <!-- 序列化的根對象 -->
        <param name="includeProperties">userList\[.*\](id|username|email),total</param>
        <param name="excludeProperties">userList\[.*\].password</param>
        <param name="noCache">true</param>
        <param name="contentType">application/json;charset=UTF-8</param>
    </result>
</action>

6. Stream 文件下載完整示例

// Action
public class ExportAction extends ActionSupport {
    private InputStream inputStream;
    private String filename;
    private long contentLength;
    
    public String execute() {
        List<User> users = userService.getAll();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try (Workbook wb = new XSSFWorkbook()) {
            Sheet sheet = wb.createSheet("Users");
            // 填充數據...
            wb.write(baos);
        }
        byte[] bytes = baos.toByteArray();
        this.inputStream = new ByteArrayInputStream(bytes);
        this.filename = "users_" + LocalDate.now() + ".xlsx";
        this.contentLength = bytes.length;
        return SUCCESS;
    }
    // getters...
}

// struts.xml
<action name="exportUsers" class="com.example.ExportAction">
    <result name="success" type="stream">
        <param name="inputName">inputStream</param>
        <param name="contentType">application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</param>
        <param name="contentDisposition">attachment;filename="${filename}"</param>
        <param name="contentLength">${contentLength}</param>
        <param name="bufferSize">8192</param>
    </result>
</action>

四、動態結果映射(代碼中決定)

public class DynamicResultAction extends ActionSupport {
    private String viewType; // jsp, json, excel
    
    public String execute() {
        if ("mobile".equals(deviceType)) return "mobileView";
        if ("api".equals(clientType)) return "jsonView";
        return SUCCESS;
    }
}

// struts.xml
<action name="dynamic" class="com.example.DynamicResultAction">
    <result name="success">/desktop.jsp</result>
    <result name="mobileView">/mobile.jsp</result>
    <result name="jsonView" type="json">
        <param name="root">data</param>
    </result>
</action>

五、常見問題排查

現象原因解決
重定向後數據丟失用 redirect 而非 chain/redirectAction,或未使用 Flash 機制改用 redirectAction 攜帶參數,或 Session/Flash 存儲
JSON 返回 406缺少 json-plugin 或 Accept 頭不匹配添加依賴,設置 contentType 參數
文件下載文件名亂碼Content-Disposition 編碼問題使用 URLEncoder.encode(filename, "UTF-8") 並設置 filename*=UTF-8''...
OGNL 表達式報錯屬性為 null 或類型不匹配Action 中初始化默認值,或使用 #attr.defaultValue

結語

<result> 是 Struts 2 視圖解耦的關鍵。掌握 11 種結果類型、parse 參數解析、全局結果/異常映射、chain 與 redirectAction 區別、JSON/Stream 參數微調,即可應對從傳統 MVC 到 REST API、文件下載、報表導出的所有視圖需求。新項目建議 Spring MVC,但維護老項目時這些配置技巧依然高頻使用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved