访问request,session和application对象

1      访问request、session和application对象

在传统的web开发中,经常会用到Servelt API中的HttpServletRequest、HttpSession和Servletcontext。Struts2框架让我们可以直接访问和设置action及模型对象的数据,这降低了对HttpServletRequest对象的使用需求,但在某些应用中,我们可能会需要在action中去访问HttpServletRequest对象以及其他两个对象,例如,用户登录成功后,我们应该将用户信息保存到Session中。

Struts2提供了多种方式来访问上述的三种对象,归结起来,可以划分为两大类:

Ø  与Servlet api 解耦的访问方式

Ø  与Servlet api耦合的访问方式

1.1    与Servlet API解耦的访问方式

为了避免与Servlet api耦合在一起,方便Action类做单元测试,Struts2对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对象

Eg:通过ActionContext来获取request ,session和application对象。

http://localhost:8080/struts2/login/index!reg.action?user.username=kevin&user.password=123

LoginAction.java

public class LoginAction1 extends ActionSupport {
	private User user;

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}
	
	public String reg(){
		ActionContext context = ActionContext.getContext();
		Map request  = (Map)context.get("request");
		Map session = context.getSession();
		Map application = context.getApplication();
		
		request.put("greeting", "欢迎您来到程序员之家");
		
		session.put("user", user);
		
		Integer count = (Integer)application.get("counter");
		if(null==count)
			count=1;
		else
			count=count++;
		application.put("counter", count);
		
		return SUCCESS;
	}
	
}

Message.jsp

<h3>${sessionScope.user.username},${requestScope.greeting} . 
  	 <br/>
  	 本站的访问量是:${applicationScope.counter}	
</h3> 

说明在Action中,对ActionContext返回的Map对象的操作,等价于对Servlet API中的HttpServletRequest,HttpSession,ServletContext对象的操作。

利用请求对象来传递数据还有一种方式,使用ActionContext类的put()方法将数据保存到ActionContext中,如下:

ActionContext.getContext().put(“greeting”,”welcome”);

然后在结果页面中,从请求对象中取出greeting属性:
${requestScope.greeting} 或者

<%=request.getAttribute(“greeting”)%>

 

 

除了利用ActionContext来获取request, session, application对象这种方式外,Action类还可以实现某些特定的接口,让struts2 框架在运行时向Action实例注入request, session 和application对象。

接口如下:

Ø  Org.apache.struts2.interceptor.RequestAware
框架利用该接口,向Action实例注入request Map对象。该接口只有一个方法,如下
public void setRequest(Map request)

Ø  Org.apache.struts2.interceptor.SessionAware
框架利用该接口,向Action实例注入sessionMap对象。该接口只有一个方法,如下:
void setSession(Map session)

Ø  Org.apache.struts2.interceptor.ApplicationAware
框架利用该接口,向Action实例注入application Map对象。该接口只有一个方法,如下:
void setApplication(Map application)

Eg:通过接口注入来获取request,session,application对象

http://localhost:8080/struts2/login/login.action?user.username=kevin&user.password=123

Login2Action.java

public class LoginAction2 implements Action, RequestAware, SessionAware,
		ApplicationAware {
	private Map request;
	private Map session;
	private Map application;

	@Override
	public String execute() throws Exception {
		request.put("greeting", "欢迎您来到程序员之家");

		session.put("user", user);

		Integer count = (Integer) application.get("counter");
		if (null == count)
			count = 1;
		else
			count = count++;
		application.put("counter", count);

		return SUCCESS;
	}

	@Override
	public void setRequest(Map request) {
		this.request = request;
	}

	@Override
	public void setSession(Map session) {
		this.session = session;
	}

	@Override
	public void setApplication(Map application) {
		this.application = application;
	}

	private User user;

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

}

在LoginAction2类实现了RequestAware,SessionAware,ApplicationAware接口,框架在运行时会调用这三个接口中的方法,向LoginAction2注入request, session, application对象。在方法中不再需要访问ActionContext。

虽然利用struts2提供的request, session 和 application对象就可以对HttpServletRequest,HttpSession,ServletContext对象中的数据进行操作,但它们毕竟是Map类型,如果我们需要调用HttpServletRequest,HttpSession,ServletContext中的特定操作,例如获取请求方法的名字(调用HttpServletRequest中的getMethod()方法),那么可以使用下一节介绍的方式来获取servlet环境中的对象。

1.2    与Servlet API耦合的访问方式

直接访问Servlet API 将使你的Action与Servlet环境耦合在一起,我们知道对于HttpServletRequest, HttpServletResponse 和ServletContext 这些对象,它们都是由Servlet容器来构造的,与这些对象绑定在一起,测试时就需要有Servlet容器,不便于Action的单元测试。但有时候,我们又确实需要直接访问这些对象,那么当然是以完成任务需求为主。

 

要直接获取HttpServletRequest 和 ServletContext对象,可以使用org.apache.strusts2.ServletActionContext类,该类是ActionContext的子类,在这个类中定义下面两个静态方法:

Ø  Public static HttpServletRequest getRequest()
得到HttpServletRequest对象

Ø  Public static ServletContext getServletContext()
得到ServletContext对象

此外,ServletActionContext类还给出了获取HttpServletResponse对象的方法,如下:

Ø  Public static HttpServletResponse getResponse()

 

  ServletActionContext类并没有给出直接得到HttpSession对象的方法,HttpSession对象可以通过HttpServletRequest对象来得到。


除了上述的方法调用得到HttpServletRequest 和 ServletContext对象外,还可以调用ActionContext 对象的 get() 方法,传递 ServletActionContext.HTTP_REQUEST 和ServletActionContext.SERVLET_CONTEXT键值来得到HttpServletRequest和ServletContext对象,如下所示:

Ø  ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST)
得到与ServletActionContext.HTTP_REQUEST键值绑定的HttpServletRequest对象

Ø  ActionContext.getContext().get(ServletActionContext.SERVLET_CONTEXT)
得到与ServletActionContext.SERVLET_CONTEXT键值绑定的ServletContext对象。

Ø  ActionContext.getContext().get(ServletActionContext.HTTP_RESPONSE)
得到HttpServletResponse对象

建议采用第一种方式来获取HttpServletRequest和ServletContext对象,这样简单清晰。

 

Eg:通过ServletActionContext来获取HttpServletRequest和ServletContext对象

LoginAction3.java

public class LoginAction3 extends ActionSupport {
	private User user;

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}
	
	public String execute() throws Exception {
		HttpServletRequest request = ServletActionContext.getRequest();
		HttpSession session = request.getSession();
		ServletContext context = ServletActionContext.getServletContext();
		
		/**
		 ActionContext ctx = ActionContext.getContext();
		 HttpServletRequest request = (HttpServletRequest)ctx.get(ServletActionContext.HTTP_REQUEST);
		 HttpSession session = request.getSession();
		 ServletContext context = (ServletContext)ctx.get(ServletActionContext.SERVLET_CONTEXT);
		 */
		
		//在请求中放置欢迎信息
		request.setAttribute("greeting", "欢迎您来到程序员之家");

		session.setAttribute("user", user);

		Integer count = (Integer) context.getAttribute("counter");
		if (null == count)
			count = 1;
		else
			count = count++;
		context.setAttribute("counter", count);

		return SUCCESS;
	}
	
}

除了利用ServletActionContext来获取HttpServletRequest对象和ServletContext对象这种方式外,Action类还可以实现ServletRequestAware 和 ServletContextAware接口,由struts2框架向Action实例注入HttpServletRequest 和 ServletContext对象。

Org.apache.struts2.interceptor.ServletRequestAware接口只有一个方法,如下:

  Void setServletRequest(HttpServletRequest  request)

Org.apache.struts2.util.ServletContextAware接口也只有一个方法:

  Void setServletContext(ServletContext context)

 

ServletRequestAware接口和ServletContextAware接口不属于同一个包,前者在org.apache.struts2.interceptor包中,后者在org.apache.struts2.util包中。

 

Eg:通过接口注入来获取HttpServletRequest和 ServletContext对象:

public class LoginAction4 extends ActionSupport implements ServletRequestAware,
		ServletContextAware {
	private User user;
	private HttpServletRequest request;
	private ServletContext context;

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String execute() throws Exception {
		HttpSession session = request.getSession();
		// 在请求中放置欢迎信息
		request.setAttribute("greeting", "欢迎您来到程序员之家");

		session.setAttribute("user", user);

		Integer count = (Integer) context.getAttribute("counter");
		if (null == count)
			count = 1;
		else
			count = count++;
		context.setAttribute("counter", count);

		return SUCCESS;
	}

	@Override
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}

	@Override
	public void setServletContext(ServletContext context) {
		this.context = context;
	}

}



你可能感兴趣的:(访问request,session和application对象)