Struts 處理請求的標準流程:
struts-config.xml 定位 ActionMappingscope 尋找/建立 ActionForm 實例form.reset() → 封裝請求參數 → form.validate()(若 validate="true")input 指定 URI;驗證通過 → 呼叫 Action.execute()ActionForward 轉向目標頁面或 Action<action path="/fullAction"
type="com.example.FullAction"
name="userForm"
input="/form.jsp">
<forward name="success" path="/success.jsp"/>
<forward name="fail" path="/fail.jsp"/>
</action>
execute() 僅在驗證通過後執行<action path="/formOnly"
type="org.apache.struts.actions.ForwardAction"
name="searchForm"
input="/search.jsp"
parameter="/result.jsp"/>
ForwardActionForm.reset()/validate() 中(存取業務層)forward,不可 redirect<action path="/actionOnly"
type="com.example.LogoutAction"
input="/login.jsp">
<forward name="success" path="/login.jsp"/>
<forward name="fail" path="/error.jsp"/>
</action>
execute() 自行從 HttpServletRequest 取參數forward 或 redirect<action path="/jspOnly"
type="org.apache.struts.actions.ForwardAction"
parameter="/static/help.jsp"/>
<action path="/step1"
type="com.example.Step1Action"
name="wizardForm"
input="/step1.jsp">
<forward name="next" path="/step2.do"/>
</action>
<action path="/step2"
type="com.example.Step2Action"
name="wizardForm"
input="/step2.jsp">
<forward name="success" path="/done.jsp"/>
</action>
關鍵挑戰:Step2 會再次呼叫 form.reset() 和 validate(),可能覆蓋 Step1 存入的資料。
// Step1Action.execute()
request.setAttribute("FROM_STEP1", Boolean.TRUE);
return mapping.findForward("next");
// Step2Form.reset()
if (request.getAttribute("FROM_STEP1") != null) return; // 保留資料
<forward name="next" path="/step2.do" redirect="true"/>
// Step1 結束前
session.setAttribute("WIZARD_DATA", form.getData());
session.setAttribute("WIZARD_ACTIVE", Boolean.TRUE);
// Step2 初始化
if (session.getAttribute("WIZARD_ACTIVE") != null) {
form.setData((Data) session.getAttribute("WIZARD_DATA"));
session.removeAttribute("WIZARD_ACTIVE");
}
<action path="/step1" ... name="inputForm" ...>
<forward name="next" path="/step2.do" redirect="true"/>
</action>
<action path="/step2" ... name="outputForm" ...> ... </action>
outputForm 顯示redirect 避免重複提交、降低耦合、分離關注點| 特性 | Forward (RequestDispatcher) | Redirect (sendRedirect) |
|---|---|---|
| 瀏覽器網址列 | 不變 | 改變為目標 URL |
| Request 物件 | 共享 | 重新建立 |
| 跨 Context | 不可 | 可 |
| 重複提交風險 | 高(F5 重送) | 低 |
| 適用場景 | 同一流程內步驟 | 流程結束、跨模組、POST 後導向 GET |
global-forwards 定義共用導航邏輯名稱