在傳統的Web開發中,經常會用到Servlet API中的HttpServletRequest、HttpSession和ServletContext。Struts 2框架讓我們可以直接訪問和設置action及模型對象的數據,這降低了對HttpServletRequest對象的使用需求,但在某些應用中,我們可能會需要在action中去訪問HttpServletRequest對象以及其他兩種對象,例如,用戶登錄成功後,我們應該將用戶信息保存到Session中。
Struts 2提供了多種方式來訪問上述的三種對象,歸結起來,可以劃分爲兩大類:與Servlet API解耦的訪問方式和與Servlet API耦合的訪問方式.
與Servlet API解耦的訪問方式
爲了避免與Servlet API耦合在一起,方便Action類做單元測試,Struts 2對HttpServletRequest、HttpSession和ServletContext進行了封裝,構造了三個Map對象來替代這三種對象,在Action中,直接使用HttpServletRequest、HttpSession和ServletContext對應的Map對象來保存和讀取數據。
要獲取這三個Map對象,可以使用com.opensymphony.xwork2.ActionContext類。
ActionContext是action執行的上下文,在ActionContext中保存了action執行所需的一組對象,包括parameters、request、session、application和locale等。ActionContext類定義瞭如下方法,用於獲取HttpServletRequest、HttpSession和ServletContext對應的Map對象。
Ø public Object get(Object key)
ActionContext類沒有提供類似getRequest()這樣的方法來獲取封裝了HttpServletRequest的Map對象。要得到請求Map對象,你需要爲get()方法傳遞參數“request”。
Ø public Map getSession()
獲取封裝了HttpSession的Map對象。
Ø public Map getApplication()
獲取封裝了ServletContext的Map對象。
通過ActionContext來獲取request、session和application對象的LoginAction:
Java代碼
- import java.util.Map;
- import com.opensymphony.xwork2.ActionContext;
- public class LoginAction {
- private String name;
- private String password;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
- @SuppressWarnings("unchecked")
- public String execute() {
- ActionContext context = ActionContext.getContext();
- Map request = (Map) context.get("request");
- Map session = context.getSession();
- Map application = context.getApplication();
- // 在請求中放置歡迎信息。
- request.put("greeting", "歡迎您來到程序員之家");
- // 在session中保存password屬性
- session.put("password", password);
- // 統計用戶訪問量,在application中保存用戶訪問量數據
- Integer count = (Integer) application.get("counter");
- if (null == count)
- count = 1;
- else
- count++;
- application.put("counter", count);
- return "success";
- }
- }
import java.util.Map; import com.opensymphony.xwork2.ActionContext; public class LoginAction { private String name; private String password; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @SuppressWarnings("unchecked") public String execute() { ActionContext context = ActionContext.getContext(); Map request = (Map) context.get("request"); Map session = context.getSession(); Map application = context.getApplication(); // 在請求中放置歡迎信息。 request.put("greeting", "歡迎您來到程序員之家"); // 在session中保存password屬性 session.put("password", password); // 統計用戶訪問量,在application中保存用戶訪問量數據 Integer count = (Integer) application.get("counter"); if (null == count) count = 1; else count++; application.put("counter", count); return "success"; } }
在成功頁面中,可以使用JSP內置的表達式語言來訪問request、session和application範圍的數據:
- <%@ page contentType="text/html;charset=GBK" %>
- <html>
- <head><title>歡迎頁面</title></head>
- <body>
- <h3>${sessionScope.username},${requestScope.greeting}。<br>
- 本站的訪問量是:${applicationScope.counter}</h3>
- </body>
- </html>
<%@ page contentType="text/html;charset=GBK" %> <html> <head><title>歡迎頁面</title></head> <body> <h3>${sessionScope.username},${requestScope.greeting}。<br> 本站的訪問量是:${applicationScope.counter}</h3> </body> </html>
除了利用ActionContext來獲取request、session和application對象這種方式外,Action類還可以實現某些特定的接口,讓Struts 2框架在運行時向Action實例注入request、session和application對象。與之對應的三個接口和它們的方法如下所示:
Ø org.apache.struts2.interceptor.RequestAware
框架利用該接口,向Action實例注入request Map對象。該接口只有一個方法,如下:
— public void setRequest(Map request)
Ø org.apache.struts2.interceptor.SessionAware
框架利用該接口,向Action實例注入session Map對象。該接口只有一個方法,如下:
— void setSession(Map session)
Ø org.apache.struts2.interceptor.ApplicationAware
框架利用該接口,向Action實例注入application Map對象。該接口只有一個方法,如下:
— void setApplication(Map application)
通過接口注入來獲取request、session和application對象的LoginAction:
Java代碼
- import java.util.Map;
- import org.apache.struts2.interceptor.ApplicationAware;
- import org.apache.struts2.interceptor.RequestAware;
- import org.apache.struts2.interceptor.SessionAware;
- @SuppressWarnings("unchecked")
- public class LoginAction2 implements RequestAware, SessionAware,
- ApplicationAware {
- private Map request;
- private Map session;
- private Map application;
- private String name;
- private String password;
- public void setRequest(Map request) {
- this.request = request;
- }
- public void setSession(Map session) {
- this.session = session;
- }
- public void setApplication(Map application) {
- this.application = application;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
- public String execute() throws Exception {
- // 在請求中放置歡迎信息。
- request.put("greeting", "歡迎您來到程序員之家");
- // 在session中保存user對象
- session.put("password", password);
- // 統計用戶訪問量,在application中保存用戶訪問量數據
- Integer count = (Integer) application.get("counter");
- if (null == count)
- count = 1;
- else
- count++;
- application.put("counter", count);
- return "success";
- }
- }
import java.util.Map; import org.apache.struts2.interceptor.ApplicationAware; import org.apache.struts2.interceptor.RequestAware; import org.apache.struts2.interceptor.SessionAware; @SuppressWarnings("unchecked") public class LoginAction2 implements RequestAware, SessionAware, ApplicationAware { private Map request; private Map session; private Map application; private String name; private String password; public void setRequest(Map request) { this.request = request; } public void setSession(Map session) { this.session = session; } public void setApplication(Map application) { this.application = application; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String execute() throws Exception { // 在請求中放置歡迎信息。 request.put("greeting", "歡迎您來到程序員之家"); // 在session中保存user對象 session.put("password", password); // 統計用戶訪問量,在application中保存用戶訪問量數據 Integer count = (Integer) application.get("counter"); if (null == count) count = 1; else count++; application.put("counter", count); return "success"; } }
LoginAction類實現了RequestAware、SessionAware和ApplicationAware接口,框架在運行時會調用這三個接口中的方法,向LoginAction2注入request、session和application對象。在execute()方法中不再需要訪問ActionContext,因此我們刪除了與之相關的代碼。