在 Struts 1.x 時代,Action 類的 execute 方法直接提供 HttpServletRequest 和 HttpServletResponse 參數,開發者能輕鬆操作 Servlet API。然而 Struts 2 採用無參數的 execute 方法,若需獲取原生 Servlet 對象,必須透過框架提供的機制。本文將系統介紹四種在 Struts 2 Action 中取得 HttpServletResponse 的方式,並附上完整代碼示例,助你根據專案需求選擇最適合的方案。
ServletResponseAware 接口(推薦)這是最標準、最符合 Struts 2 設計哲學的方式。只需讓 Action 類實現 org.apache.struts2.interceptor.ServletResponseAware 接口,框架會在調用 execute 前自動注入 Response 對象。
package action;
import com.opensymphony.xwork2.ActionSupport;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.ServletResponseAware;
public class MyAction extends ActionSupport implements ServletResponseAware {
private HttpServletResponse response;
@Override
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
@Override
public String execute() throws Exception {
response.getWriter().write("通過 ServletResponseAware 獲取 Response");
return NONE;
}
}
優點:類型安全、易於測試、符合依賴注入原則。
擴展:同理,實現 ServletRequestAware、SessionAware、CookiesAware 可分別獲取 Request、Session、Cookies 等對象。
RequestAware 接口(較繁瑣)實現 org.apache.struts2.interceptor.RequestAware 可獲得一個 Map,裡面包含 OgnlValueStack,再從中取出 Servlet API 對象。代碼如下:
package action;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.StrutsStatics;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.OgnlValueStack;
import org.apache.struts2.interceptor.RequestAware;
public class FirstAction extends ActionSupport implements RequestAware {
private Map requestMap;
private HttpServletResponse response;
@Override
public void setRequest(Map request) {
this.requestMap = request;
}
@Override
public String execute() throws Exception {
OgnlValueStack stack = (OgnlValueStack) requestMap.get("struts.valueStack");
response = (HttpServletResponse) stack.getContext().get(StrutsStatics.HTTP_RESPONSE);
response.getWriter().write("通過 RequestAware 獲取 Response");
return NONE;
}
}
此法需手動從 ValueStack 取值,步驟較多,一般不推薦作為首選,僅作參考。
ActionContext 靜態獲取(簡潔)org.apache.struts2.ActionContext 是線程局部變量,隨時可調用 getContext() 取得上下文,再以 StrutsStatics 常數為鍵獲取對象:
HttpServletResponse response = (HttpServletResponse)
ActionContext.getContext().get(StrutsStatics.HTTP_RESPONSE);
HttpServletRequest request = (HttpServletRequest)
ActionContext.getContext().get(StrutsStatics.HTTP_REQUEST);
優點是不用實現接口,隨時可用;缺點是依賴靜態方法,單元測試時需模擬 ActionContext。
ServletActionContext 工具類(最簡單、最常用)Struts 2 專門提供 org.apache.struts2.ServletActionContext,封裝了常用 Servlet API 的直接獲取方法:
HttpServletResponse response = ServletActionContext.getResponse();
response.getWriter().write("hello world");
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = ServletActionContext.getRequest().getSession();
這是實務上最輕量、最直觀的方式,幾乎所有專案均採用此法。
掌握這四種方式,你就能在 Struts 2 專案中靈活應對各類 Servlet API 操作需求。