Struts2操作request、session和application对象
Struts 2提供了多种方式来访问上述的三种对象,归结起来,可以划分为两大类:与Servlet API解耦的访问方式和与Servlet API耦合的访问方式。
与Servlet API解耦的访问方式(IoC方式)
为了避免与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对象的LoginAction1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
package action; import java.util.Map; import dbPackage.User; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionContext; public class LoginAction1 implements Action { private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } @SuppressWarnings("unchecked") @Override public String execute() throws Exception { if("zhangsan".equals(user.getUsername())&& "1234".equals(user.getPassword())) { ActionContext context = ActionContext.getContext(); Map request = (Map)context.get("request"); Map session = context.getSession(); Map application = context.getApplication(); //在请求中放置欢迎信息。 request.put("greeting", "欢迎您来到程序员之家"); //在session中保存user对象 session.put("user", user); //统计用户访问量,在application中保存用户访问量数据 Integer count = (Integer)application.get("counter"); if(null == count) count=1; else count++; application.put("counter", count); return SUCCESS; }else { return ERROR; } }} |
在成功页面中,可以使用JSP内置的表达式语言来访问request、session和application范围的数据,代码如例3-12所示。
例3-12 success.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<%@ page contentType="text/html;charset=GBK" %> <html> <head><title>欢迎页面</title></head> <body> <h3>${sessionScope.user.username},${requestScope.greeting}。<br> 本站的访问量是:${applicationScope.counter}</h3> </body> </html> |
与Servlet API耦合的访问方式(非IoC方式)
要获得上述对象,关键Struts 2.0中com.opensymphony.xwork2.ActionContext类。我们可以通过它的静态方法getContext()获取当前 Action的上下文对象。 另外,org.apache.struts2.ServletActionContext作为辅助类(Helper Class),可以帮助您快捷地获得这几个对象。
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
HttpSession session = request.getSession();
如果你只是想访问session的属性(Attribute),你也可以通过ActionContext.getContext().getSession()获取或添加session范围(Scoped)的对象。
Struts2中Session的使用
在Struts2里,如果需要在Action中使用session,可以通过下面两种方式得到
1.通过ActionContext class中的方法getSession得到
2.Action实现org.apache.struts2.interceptor.SessionAware接口的方式来对session进行操作
下面先看一个采用第一种方式,在action中得到session的例子
package s2.ex.action;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class SessionTestAction extends ActionSupport {
public String execute() {
ActionContext actionContext = ActionContext.getContext();
Map session = actionContext.getSession();
session.put("USER_NAME", "Test User");
return SUCCESS;
}
}
在这个例子中,通过ActionContext得到session,并往session里放置一个key为USER_NAME,值为Test User的内容。
下面是一个实现org.apache.struts2.interceptor.SessionAware接口来对session操作的例子
package s2.ex.action;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
import com.opensymphony.xwork2.ActionSupport;
public class SessionTest1Action extends ActionSupport implements SessionAware {
private Map session;
public void setSession(Map session) {
this.session = session;
}
public String execute() {
this.session.put("USER_NAME", "Test User 1");
return SUCCESS;
}
}
在这个例子中实现了接口SessionAware中的setSession方法。
上面两种方式都可以得到session,能实现的功能都是一样的。
这里推荐通过第二种方式来使用session,原因是便于做单体测试,用第二种方式,只需要构造一个Map就可以对action class进行单体测试了。
在一个项目中可能会有很多action都需要用到session,如果每个action都来实现org.apache.struts2.interceptor.SessionAware这个接口,可能会显得比较麻烦,所以建议作一个抽象的BaseAction类来实现org.apache.struts2.interceptor.SessionAware接口,以后所有的action只要继承这个BaseAction就可以了。
下面是一个如何在JSP中使用session的例子。
<%@ page contentType="text/html; charset=UTF-8" %>
<%@page pageEncoding="utf-8" %>
<%@taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Session Test</title>
</head>
<body>
<h1><s:property value="#session.USER_NAME"/></h1>
</body>
</html>
一般在项目中往往会往session里放置一个Object,必如说user,user里有个boolean admin和String userName,如果user里存在isAdmin的方法,在jsp中可以通过<s:if test="#session.user.admin">来判断用户有没有管理权限,通过<s:property value="#session.user.userName">或者来取得用户名。好东西!!!