在传统的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:
- 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范围的数据:
Js代码
- <%@ 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:
- 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,因此我们删除了与之相关的代码。