Struts2 以「Action 脫離 Servlet API」為設計目標,但實務上仍常需存取 HttpServletRequest、HttpServletResponse、HttpSession、ServletContext。本文整理三種主流方式,供開發者依情境選擇。
實作對應介面,框架自動注入:
ServletRequestAware → setServletRequest(HttpServletRequest)ServletResponseAware → setServletResponse(HttpServletResponse)SessionAware → setSession(Map<String, Object>)(注入 Session Map)ApplicationAware → setApplication(Map<String, Object>)public class MyAction extends ActionSupport
implements ServletRequestAware, SessionAware {
private HttpServletRequest request;
private Map<String, Object> session;
@Override
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
}
優點:型別安全、易測試、符合 IoC 精神。
缺點:需實作多個介面、程式碼較冗長。
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
HttpSession session = ServletActionContext.getRequest().getSession();
ServletContext application = ServletActionContext.getServletContext();
優點:隨時可用、無需實作介面。
缺點:強耦合 Servlet API、單元測試需 Mock 靜態方法(需 PowerMock 等工具)。
ActionContext ctx = ActionContext.getContext();
// 取得請求參數 Map
Map<String, Object> params = ctx.getParameters();
// 存取/設定 Session
Map<String, Object> session = ctx.getSession();
session.put("key", value);
// 存取/設定 Application
Map<String, Object> application = ctx.getApplication();
application.put("key", value);
優點:統一用 Map 操作、可跨執行緒存取(ActionContext 為 ThreadLocal)。
缺點:無法直接拿到原生 HttpServletRequest/Response 物件(如需設定 Header、Cookie 仍需方式二)。
| 需求 | 推薦方式 | 備註 |
|---|---|---|
| 讀取請求參數、Header、Cookie | 方式一 或 方式二 | 方式一型別安全 |
| 設定 Response Header、Cookie、狀態碼 | 方式二 | 需原生 Response 物件 |
| Session/Application 讀寫屬性 | 方式一 (Map) 或 方式三 | 方式三語法最簡潔 |
| 單元測試友善 | 方式一 | 易 Mock Map 介面 |
ServletRequestAware、SessionAware,兼顧型別安全與測試性。ServletActionContext.getResponse()。Struts2 提供多元存取 Servlet API 的管道,理解各方式優劣與適用場景,能寫出更乾淨、可測試的 Action 代碼。原則上「能用 Aware 介面解決,就不直接呼叫靜態工具類」。