Struts2学习札记(三) Struts2中访问request,session,和application对象

Struts2学习笔记(三) Struts2中访问request,session,和application对象
访问request,session,和application对象
    Struts2提供了多种方式来访问request,session,application三种对象,归结起来,可以划分为两大类,与Servlet API解耦方式和与Servet API耦合的访问方式.
1.与Servlet API 解耦的访问方式:
    为了避免与Servlet API耦合在一起骑,为方便Action类做单元测试,Struts2对
    HttpServletRequest,HttpServletResponse和ServletContext进行了封装,构
    造了三个Map对象来替代这三种对象,要获取这三个Map对象,可以使用
    com.opensymphony.xwork2.AcionContext来获取,
      public Object get(String key)
   ActionContext类没有提供类似于getRequest()这样的方法类获取封装了HttpServletRequest的Map对象,要的到请求Map对象,需要传递参
        数”request”
            public Map getSession()
       获取封装了HttpSession的Map对象.
           public Map getApplication()
       获取封装了ServletContext的Map对象.
       看个实例吧:
           新建Action类ServletActio
        
package org.struts2lesson.ch03.action;
import java.util.Map;
import org.struts2lesson.ch03.model.User;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ModelDriven;
public class ServletAction implements Action,ModelDriven<User>
{
	private User user = new User();
	
	public String execute() throws Exception
	{
		if("zhangsan".equals(user.getUsername()) && "1234".equals(user.getPassword()))
		{
			
			ActionContext context = ActionContext.getContext();
             //获取HttpServletRequest对象
	Map request = (Map)context.get("request");
//获取HttpSession对象
Map session = (Map)context.getSession();		
//获取ServletContext对象
Map application = (Map)context.getApplication(); 
			//在请求request中放置欢迎信息
			request.put("greeting", "欢迎您学习Struts2!");
			
			//在Session中保存user对象
			session.put("user", user);
			
			//统计用户访问量,在application中保存用户数据访问量
			Integer count = (Integer)application.get("counter");
			if(count == null)
			{
				count = 1;
			}
			else
			{
				count++;
			}
			application.put("counter", count);
			
			return SUCCESS;
		}
		else
		{
			return ERROR;
		}
	}
	public User getModel()
	{
		return user;
	}
}
新建页面successServlet.jsp.代码如下:
         <h3>
          ${sessionScope.user.username },${requestScope.greeting }.<br>
          本站的访问量是:${applicationScope.counter }
      </h3>
       
         说明:当然也可以使用ActionContext类的put方法直接将数据保存到
               ActionContext中,代码如下:
               ActionContext.getContext().put(“greeting”,”欢迎光临”);
           然后在页面中,从请求对象中取出greeting属性,如下所示:
                ${requestScope.greeting }或
                <%=request.getAttribute(“greeting”) %>
         深入说明:
              之所以ActionContext中保存的数据能被从请求中得到,是因为在Struts2
中的org.apache.struts2.dispatcher.StrutsRequestWrapper类,是HttpServletRequest的包装类,重写了getAttribute()方法,在这个方法中,它首先在请求对象中查找,如果没有找到,则到ActionContext中查找.这是为什么在ActionConext中保存的数据能够从请求对象中得到的原因。

   除了利用ActionContext类可以获取request,session,application对象这种方式外,Action还可以实现某些特定的接口,然Struts2框剪在运行时向实例注入
request,session,application对象,与之对应的三个接口和他们的方法如下:
   org.apache.struts2.interceptor.RequestAware类,框架利用该接口,向Action
实例注入request Map对象,该接口只有一个方法,是
   public void setRequest(Map request)
   org.apache.struts2.interceptor.SessionAware类,框架利用该接口,向Action实例注入session Map对象,该接口只有一个方法,是
   public void setSession(Map session)
   org.apache.struts2.interceptor.AplicationAware类,框架利用该接口,向Action实例注入aplication Map对象,该接口只有一个方法,是
   public void setAplication(Map aplication)
  
   看段代码演示吧:
新建类Servlet2Action,代码如下
     
package org.struts2lesson.ch03.action;
import java.util.Map;
import org.apache.struts2.interceptor.ApplicationAware;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.SessionAware;
import org.struts2lesson.ch03.model.User;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ModelDriven;

public class Servlet2Action implements Action,ModelDriven<User>,RequestAware,SessionAware,
ApplicationAware
{
	private User user = new User();
	private Map request;
	private Map session;
	private Map application;

	public String execute() throws Exception
	{
		if("zhangsan".equals(user.getUsername()) && "1234".equals(user.getPassword()))
		{
			//在请求request中放置欢迎信息
			request.put("greeting", "欢迎您学习Struts2!");
			//在Session中保存user对象
			session.put("user", user);
			//统计用户访问量,在application中保存用户数据访问量
			Integer count = (Integer)application.get("counter");
			if(count == null)
			{
				count = 1;
			}
			else
			{
				count++;
			}
			application.put("counter", count);
			
			ActionContext.getContext().put("greeting", "欢迎您来学习Struts2");
			return SUCCESS;
		}
		else
		{
			return ERROR;
		}
	}
	
	public User getModel()
	{
		return user;
	}
	public void setRequest(Map request)
	{
		this.request = request;
	}
	public void setSession(Map session)
	{
		this.session = session; 
	}
	public void setApplication(Map application)
	{
		this.application = application;
	}
}
  
实现了RequestAware,SessionAware,ApplicationAware接口,就不用再去
ActionContext里面去取数据了.
   说明:
虽然利用Struts2提供的类和方法,可以获取
HttpServletRequest,HttpServletSession和ServletContext对象,但他们毕竟是Map类型的,如果需要调用HttpServletRequest,HttpServletSession和ServletContext的特定操作,例如获取请求方法的名字等,就无能为力了,只能
使用下面将要介绍到的与Servlet API 耦合的访问方式.

2.与Servlet API 耦合的访问方式:
要直接获取HttpServletRequest和ServletContext对象,可以使用
org.apache.struts2.ServletActionContext类,该类是ActionContext的子类,定义了如下两个静态方法:
     public static HttpServletRequest getRequest()
    用来得到HttpServletRequest对象.
    public static ServtletContext getServletContext()
    用来得到ServletContext对象.
    此外,ServletActionContext还给出了获取HttpServletResponse对象的方法:
     public static HttpServletResponse getResponse()
    用来得到HttpServletResponse对象.
    注意,ServletActionContext并没有直接给出HttpSession对象的方法,HttpSession对象可以通过HttpServletRequest对象来得到.
    写段代码吧:
     
package org.struts2lesson.ch03.action;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import org.struts2lesson.ch03.model.User;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ModelDriven;

public class Servlet3Action implements Action,ModelDriven<User>
{
	private User user = new User();
	
	public String execute() throws Exception
	{
if("zhangsan".equals(user.getUsername()) && 
"1234".equals(user.getPassword()))
		{
			//在请求request中放置欢迎信息
HttpServletRequest request = 
ServletActionContext.getRequest();
			HttpSession session = request.getSession();
ServletContext context = 
ServletActionContext.getServletContext();
			
			request.setAttribute("greeting", "欢迎您学习Struts2!");
			//在Session中保存user对象
			session.setAttribute("user", user);
			//统计用户访问量,在application中保存用户数据访问量
Integer count = (Integer)context.getAttribute("counter");
			if(count == null)
			{
				count = 1;
			}
			else
			{
				count++;
			}
			context.setAttribute("counter", count);
			return SUCCESS;
		}
		else
		{
			return ERROR;
		}
	}
	
	public User getModel()
	{
		return user;
	}
}

   返回successServlet.jsp页面不用动,配置好运行就可以了。

   除了用ServletActionContext来获取HttpServletRequest和ServletContex
对象外,Action类还可以实现ServletRequestAware和ServltContextAware接口.
向Struts2框架注入HttpServletRequest和ServletContext对象.
   org.apache.struts2.interceptor.ServletRequestAware接口只有一个方
法,如下所示:
   public void setServletRequest(HttpServletRequest request)
   org.apache.struts2.utils.ServletContextAware接口只有一个方
法,如下所示:
   public void setServletContext(ServletContext context)

说明:两个类没有在同一个包中,比较让人费解.
示例代码如下:
   
package org.struts2lesson.ch03.action;

import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.util.ServletContextAware;
import org.struts2lesson.ch03.model.User;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ModelDriven;
public class Servlet4Action implements Action,ModelDriven<User>,ServletRequestAware,ServletContextAware
{	
	private User user = new User();
	private HttpServletRequest request;
	private ServletContext context;
	public String execute() throws Exception
	{
if("zhangsan".equals(user.getUsername()) && 
"1234".equals(user.getPassword()))
		{
			//在请求request中放置欢迎信息
HttpServletRequest request = 
ServletActionContext.getRequest();
			HttpSession session = request.getSession();
ServletContext context = 
ServletActionContext.getServletContext();
			request.setAttribute("greeting", "欢迎您学习Struts2!");
			//在Session中保存user对象
			session.setAttribute("user", user);
//统计用户访问量,在application中保存用户数据访问量			
Integer count =  
 (Integer)context.getAttribute("counter");
			if(count == null)
			{
				count = 1;
			}
			else
			{
				count++;
			}
			context.setAttribute("counter", count);
			return SUCCESS;
		}
		else
		{
			return ERROR;
		}
	}
	
	public User getModel()
	{
		return user;
	}
	public void setServletRequest(HttpServletRequest request)
	{
		this.request = request;
	}
	public void setServletContext(ServletContext context)
	{
		this.context = context;
	}
}
总结:本小结由一个登录程序开始,介绍了Struts2中接收用户输入数据的三种方式:
1> 使用领域对象来接收用户输入
2> 使用Action实现ModelDriven接口来简化对对象的操作.
3> 直接使用Action的属性来接收用户操作.

接着介绍了在Action中如何访问request,session,
和application(即ServletContext)对象,在这里,可以使用Struts2提供的Map对象来访问HttpServletRequest,HttpSession和ServletContext对象也可以直接访问Servlet环境中的这三个对象.,