勿谓今日不学而有来日,勿谓今年不学而有来年。
日月逝矣,岁不我延。

在Action类中访问Web资源

 

什么是Web资源

Web资源分为静态资源动态资源两种。简单来说:

静态资源:一般客户端发送请求到web服务器,web服务器从内存在取到相应的文件,返回给客户端,客户端解析并渲染显示出来。

动态资源:一般客户端请求的动态资源,先将请求交于web容器,web容器连接数据库,数据库处理数据之后,将内容交给web服务器,web服务器返回给客户端解析渲染处理。

本文中的Web资源特指HttpServletRequest、HttpServletResponse、HttpSession、 ServletContext原生的Servlet API。

 

为什么访问Web资源

Struts2作为一个B/S应用的Controller必然需要访问Web资源,如:向域对象读写属性、获取Cookie、获取Session、获取relpath等操作。

如何访问Web资源

访问方式有两种:通过与Servlet API解耦通过与Servlet API耦合。下面详细介绍一下这两种方法,一下两种方式的示例代码在我的 GitHub上可以找到。

与Servlet API解耦的方式

既然是解耦的额方式,所以只能访问有限的Servlet API对象,且只能访问有限的原生方法。如:读取请求参数、读写域对象的属性、使Session失效等。

Struts2 对 HttpServletRequest, HttpSessionServletContext 进行了封装, 构造了 3 个 Map 对象来替代这 3 个对象, 在 Action 中可以直接使用 HttpServletRequest, HttpServletSession, ServletContext 对应的 Map 对象来保存和读取数据。

具体实现

>使用ActionContext

ActionContext 是 Action 执行的上下文对象, 在 ActionContext 中保存了 Action 执行所需要的所有对象, 包括 parameters, request, session, application 等。

1、获取ActionContext对象

ActionContext actionContext=ActionContext.getContext();

2、获取application对应的Map 并添加一个属性
通过调用ActionContext的getApplication()方法获取Map

Map<String,Object> applicationMap=actionContext.getApplication();
Object date= applicationMap.get(“date”);//在index页面中赋值
applicationMap.put(“date”, date);

3、获取session对应的Map

Map<String,Object> sessionMap=actionContext.getSession();
sessionMap.put(“sessionMapKey”, “sessionMapValue”);

4、获取request对应的Map
ActionContext并没有提供getrequest方法开获取request对象
只能调用get方法传入(键)参数request获取

Map<String,Object> requestMap=(Map<String, Object>) actionContext.get(“request”);
requestMap.put(“requestMapKey”, “requestMapValue”);

5、获取请求参数对应的Map 并获取指定参数
请求参数对应的Map的key是参数名,value是参数值数组(复选框等情况)。
getParameters与上面的几个相同为Map<String,Object>并不是Map<String,String[]>.此处感觉直接返回Map<String,String[]>更好,省的下面再强转。
求参数对应的Map只能get不能put,put了也不起作用。

Map<String,Object> parametersMap=actionContext.getParameters();
System.out.println(((String[])parametersMap.get(“name”))[0]);

>使用XxxAware接口

Struts2通过Aware接口已经把Map传递到了Action(依赖注入),在Action中只需要接收即可实现对Servlet API对象及其方法的访问。如下:

package cn.llanc.GetWebResources;

import java.util.Map;

import org.apache.struts2.interceptor.ApplicationAware;
import org.apache.struts2.interceptor.ParameterAware;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.SessionAware;

public class TestAwareAction implements ApplicationAware,SessionAware,RequestAware,ParameterAware
{
	private Map<String,Object> application;
	private Map<String,Object> session;
	private Map<String,String[]> parameters;
	private Map<String,Object> request;
	//Struts2通过Aware接口已经把Map传递进来(依赖注入),在此只需要接收。
	public String  execute()
	{
		//获取application中的属性date向application中添加属性 date
		Object date=application.get("date");
		application.put("dateNew", date);

		//读写session对象的属性
		session.put("sessionKey", "sessionValue");
		
		//读写request对象的属性
		request.put("requestKey", "requestValue");
		
		//读写parameters对象的属性
		System.out.println(parameters.get("name")[0]);
		return "success";
	}

	@Override
	public void setApplication(Map<String, Object> arg0)
	{
		//绑定对象
		this.application=arg0;
		
	}

	@Override
	public void setParameters(Map<String, String[]> arg0)
	{
		this.parameters=arg0;
		
	}

	@Override
	public void setRequest(Map<String, Object> arg0)
	{
		this.request=arg0;
		
	}

	@Override
	public void setSession(Map<String, Object> arg0)
	{
		this.session=arg0;
		
	}
}

使用建议

若一个 Action 类中有多个 action 方法, 且多个方法都需要使用域对象的 Map 或 parameters, 则建议使用
Aware 接口的方式

关于SessionMap

Session对应的Map本身就是一个SessionMap(可以通过getClass()看出),其中有一个invalidate()方法,即强制转换后可以通过直接调用改方法来使当前SessionMap对应的Session失效。如下:

session.put("sessionKey", "sessionValue");
		System.out.println(session.getClass());
		if(session instanceof SessionMap) {
			SessionMap sm=(SessionMap)session; //强制转换成SessionMap
			sm.invalidate();
			System.out.println("Session被销毁!");
		}

与Servlet API耦合的方式

耦合的方式可以访问更多地Servlet API对象,且可以调用更多的原生法。

具体实现

>使用ServletActionContext

注意,Session对象可以直接通过Requset对象获得。

HttpServletRequest request=ServletActionContext.getRequest();
		request.setAttribute("requestKey", "requestValue");
		
		HttpSession session =request.getSession();//ServletActionContext.getRequest().getSession();
		session.setAttribute("sessionKey", "sessionValue");
		
		ServletContext servletContext=ServletActionContext.getServletContext();
		servletContext.setAttribute("servletContextKey", "servletContextValue");

 

>实现ServletXxxAware接口

实现ServletXxxAware接口也是通过依赖注入实现的,同ServletActionContext的方式,ServletXxxAware也没有ServletSessionAware接口,但我们依然可以通过Request对象来获取Session对象。下面是几个对象的获取:

public class TestServletAwareAction implements ServletRequestAware,ServletContextAware
{

	private HttpServletRequest request;
	
	private ServletContext servletContext;
	
	//private HttpSession session=request.getSession();
	
	public String execute()
	{
		request.getSession().setAttribute("sessionKey", "sessionValue");
	
		return "success";
		
	}

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

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

上面代码中,如果定义全局的Session则会报错:Unable to instantiate Action,,,,,,,,,defined for ‘,,,’ in namespace ‘/,,,’null。我暂时还不知道原因,请知道的网友,在下方告诉我一下,感激不尽!

小结

这个知识点我用了几天才看完的,主要是期间一直有事情打扰拖慢了进度;

Struts2访问Web资源的方式大致就是以上几种,我们应该根据实际项目需要来选取合适的实现方式,都应该掌握,不能死认一种。

天不言而四时行,地不语而百物生.

赞(0)
未经允许不得转载:喋喋不休 » 在Action类中访问Web资源

评论 抢沙发

评论前必须登录!

 

精品网站

有券无忧电脑壁纸精选