DispatchAction 允許單一 Action 類別包含多個業務方法,透過請求參數(預設 parameter 屬性指定參數名)決定呼叫哪個方法。本文示範基本用法、unspecified 預設處理,並進階解決「參數為空、方法不存在、遞迴調用」三大邊界問題。
package action;
import org.apache.struts.actions.DispatchAction;
import javax.servlet.*;
import javax.servlet.http.*;
public class MyDispatchAction extends DispatchAction {
// 對應 language=fr
public ActionForward fr(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
forwardTo(request, response, "/newGlobal.jsp?language=fr");
return null;
}
// 對應 language=en
public ActionForward en(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
forwardTo(request, response, "/newGlobal.jsp?language=en");
return null;
}
// 無參數或參數無對應方法時調用
protected ActionForward unspecified(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
forwardTo(request, response, "/newGlobal.jsp?language=zh");
return null;
}
private void forwardTo(HttpServletRequest request, HttpServletResponse response, String path) {
try {
RequestDispatcher rd = request.getRequestDispatcher(path);
rd.forward(request, response);
} catch (Exception e) {}
}
}
<action path="/locale"
type="action.MyDispatchAction"
parameter="language" />
parameter="language" 指定請求參數名。測試 URL:
/locale.do?language=en → 英文頁/locale.do?language=fr → 法文頁/locale.do → 中文頁(unspecified)/locale.do?language=(空字串)→ 拋出 NoSuchMethodException/locale.do?language=unknown(方法不存在)→ 同上execute 或 perform → 觸發遞迴調用dispatchMethod 與 getMethodName// 處理空字串、方法不存在
protected ActionForward dispatchMethod(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response,
String name) throws Exception {
if (name != null && name.equals("")) name = null; // 空字串視為無參數
try {
return super.dispatchMethod(mapping, form, request, response, name);
} catch (NoSuchMethodException e) {
name = null; // 方法不存在轉向 unspecified
return super.dispatchMethod(mapping, form, request, response, name);
}
}
// 防止 execute/perform 遞迴
protected String getMethodName(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response,
String parameter) throws Exception {
String methodName = super.getMethodName(mapping, form, request, response, parameter);
if ("execute".equals(methodName) || "perform".equals(methodName)) {
return null; // 強制轉向 unspecified
}
return methodName;
}
| 請求 | 結果 |
|---|---|
/locale.do?language= | 中文頁(unspecified) |
/locale.do?language=unknown | 中文頁(unspecified) |
/locale.do?language=execute | 中文頁(避免遞迴) |