Result 是 Struts 2 處理請求的第二階段:根據業務邏輯結果選擇視圖。本文全面解析 Result 類型體系、參數配置、動態導向機制、全局結果集與實戰最佳實踐。
| 類型名 | 實現類 | 用途 |
|---|---|---|
| dispatcher | ServletDispatcherResult | 預設,轉發到 JSP/頁面 |
| redirect | ServletRedirectResult | 客戶端重導向 (302) |
| redirectAction | ServletActionRedirectResult | 重導向到另一 Action |
| chain | ActionChainResult | Action 鏈轉發(共享請求) |
| stream | StreamResult | 文件下載、二進制流輸出 |
| json | JSONResult | AJAX 返回 JSON(需 json-plugin) |
| freemarker | FreemarkerResult | FreeMarker 模板渲染 |
| velocity | VelocityResult | Velocity 模板渲染 |
| xslt | XSLTResult | XML/XSLT 轉換 |
| plainText | PlainTextResult | 原始文本輸出(如源碼) |
| httpheader | HttpHeaderResult | 控制 HTTP 狀態碼/頭 |
<action name="hello" class="com.example.HelloAction">
<result>/hello.jsp</result>
</action>
<action name="hello" class="com.example.HelloAction">
<result name="success" type="dispatcher">
<param name="location">/hello.jsp</param>
<param name="parse">true</param> <!-- 解析 OGNL 表達式 -->
</result>
<result name="error" type="dispatcher">/error.jsp</result>
<result name="input" type="dispatcher">/input.jsp</result>
</action>
<action name="user" class="com.example.UserAction">
<result>/user_list.jsp</result>
<result name="create">/user_form.jsp</result>
<result name="edit">/user_form.jsp</result>
<result name="delete" type="redirectAction">user</result>
<result name="error">/error.jsp</result>
</action>
目標資源路徑。支援 OGNL 表達式(parse="true" 時):
<result name="success" type="dispatcher">
<param name="location">/user/${userId}/detail.jsp</param>
</result>
true(預設):解析 location 中的 OGNL 表達式。false:按字面路徑處理,效能略高。
| 參數 | 說明 |
|---|---|
| parse | 是否解析 OGNL(預設 true) |
| anchor | 錨點,如 #section1 |
| encode | 是否 URL 編碼參數(預設 true) |
<result name="download" type="stream">
<param name="contentType">application/octet-stream</param>
<param name="inputName">inputStream</param> <-- Action 的 getInputStream() -->
<param name="contentDisposition">attachment;filename="${downloadFileName}"</param>
<param name="bufferSize">4096</param>
</result>
<result name="ajax" type="json">
<param name="root">dataMap</param> <-- 序列化的根對象(需有 getter) -->
<param name="includeProperties">userList\.[^,]+</param> <-- 正則包含 -->
<param name="excludeProperties">password,secret</param> <-- 排除敏感字段 -->
<param name="ignoreHierarchy">false</param>
<param name="encodeAsUTF8">true</param>
</result>
public class DynamicAction {
private String nextPage; // 對應 getter
public String execute() {
// 業務邏輯決定導向
if (isAdmin) nextPage = "/admin/dashboard.jsp";
else nextPage = "/user/home.jsp";
return "dynamic";
}
public String getNextPage() { return nextPage; }
}
<action name="dynamic" class="com.example.DynamicAction">
<result name="dynamic" type="dispatcher">${nextPage}</result>
</action>
<action name="goto" class="com.example.GotoAction">
<result name="go" type="redirectAction">
<param name="actionName">${targetAction}</param>
<param name="namespace">${targetNamespace}</param>
<param name="id">${entityId}</param>
</result>
</action>
<package name="base" extends="struts-default">
<global-results>
<result name="error">/common/error.jsp</result>
<result name="login" type="redirectAction">LoginAction!input</result>
<result name="noPermission" type="redirectAction">AccessDeniedAction</result>
</global-results>
</package>
所有繼承 base 的包自動擁有。Action 可同名覆蓋。
| 場景 | 推薦 Result 類型 | 關鍵配置 |
|---|---|---|
| 普通頁面跳轉 | dispatcher(預設) | location 指向 JSP |
| 表單提交後 | redirect / redirectAction | PRG 模式,防重複提交 |
| 文件下載 | stream | inputName、contentDisposition |
| AJAX 回調 | json | root、excludeProperties |
| 多步驟流程 | chain | 共享 request 範圍數據 |
| REST 風格 API | httpheader + stream/json | 控制狀態碼、Content-Type |
contentDisposition 中檔名需 URLEncoder.encode(fileName, "UTF-8")。excludeProperties 排除反向關聯,或使用 DTO。Struts 2 Result 機制靈活強大。掌握類型選擇、參數配置、動態導向、全局複用四大核心,即可應對 95% 的視圖導向場景。實戰中堅持:表單提交用 redirect、AJAX 用 json、下載用 stream、錯誤頁用 global-results,配置清晰、維護無憂。