WEB资源,指的HttpServletRequest、HttpSession、ServletContext等原生Servlet API。由于Struts2实现了和Servlet API的解耦,因此访问这类资源要通过特殊的方法:
①使用ActionContext
②实现XxxAware接口
一、ActionContext
为了避免和Servlet API耦合,方便Action做单元测试,对HttpServletRequest、HttpSession、ServletContext进行了封装,构造了三个Map对象来替代这三个对象。在Action中可以直接用HttpServletRequest、HttpSession、ServletContext对应的Map对象来保存和读取数据。
首先获得一个actionContext对象,采用Action类中的静态方法获得。
ActionContext ac = ActionContext.getContext();
之后,分别可以获得各类Map
// Application
Map<String, Object> applicationMap = ac.getApplication();
applicationMap.put("one", "1");
//session
Map<String, Object> sessionMap = ac.getSession();
sessionMap.put("two", "2");
//request
Map<String, Object> requestMap = (Map<String, Object>) ac.get("request");
requestMap.put("three", "3");
由于ActionContext中并没有提供getRequest方法来获取request的map,因此需要需要手工调用get方法,传入“request”字符串来获得对应map。
也可以获得请求参数:
//parameters
Map<String, Object> parametersMap = ac.getParameters();
parametersMap.get("name");
System.out.println(((String[])parametersMap.get("name"))[0]);
注意get方法返回的是一个数组,因此在接收取值的时候应该注意。
但是这个map只能够读取,不能够写入。
二、XxxAware接口
通过使Action类继承xxxAware接口,可以获得对应的Map对象,也可以直接获得Servlet API实例。同时在该Action类中要覆写一个setXxx方法。
implement ApplicationAware ----------------------> setApplication()
implement SessionAware ----------------------> setSession()
implement RequestAware ----------------------> setRequest()
implement ParameterAware ----------------------> setParameters()
之后,在类内定义一个private类型的对象,将参数注入对象即可,如下:
private Map<String, String[]> parameters;
@Override
public void setParameters(Map<String, String[]> arg0) {
// TODO Auto-generated method stub
this.parameters = arg0;
}
private Map<String, Object> request;
@Override
public void setRequest(Map<String, Object> arg0) {
// TODO Auto-generated method stub
this.request = arg0;
}
private Map<String, Object> session;
@Override
public void setSession(Map<String, Object> arg0) {
// TODO Auto-generated method stub
this.session = arg0;
}
private Map<String, Object> application;
@Override
public void setApplication(Map<String, Object> arg0) {
// TODO Auto-generated method stub
this.application = arg0;
}
可以注意到,以上代码依然只是获得了Map对象而不是直接的Servlet API原生对象。要获得直接的对象,可以采取以下方法:
继承ServletContextAware,ServletRequestAware,ServletResponseAware。分别覆写setXxx方法。如下:
private HttpServletResponse response;
@Override
public void setServletResponse(HttpServletResponse arg0) {
// TODO Auto-generated method stub
this.response = arg0;
}
private HttpServletRequest request;
@Override
public void setServletRequest(HttpServletRequest arg0) {
// TODO Auto-generated method stub
this.request = arg0;
}
private ServletContext sc;
@Override
public void setServletContext(ServletContext arg0) {
// TODO Auto-generated method stub
this.sc = arg0;
}
同样是注入的思想,可以直接获得HttpServletRequest对象,HttpServletResponse对象,ServletContext对象。如果要获得HttpSession对象,直接用request.getSession即可,用获得的HttpServletRequest对象获取session对象。
三、借助ServletActionContext类直接访问Servlet API
该类中都是静态static方法,不需要额外的继承什么接口或者继承类。
request = ServletActionContext.getRequest();
reponse = ServletActionContext.getResponse();
Ps:若一个一个Action类中有多个action方法都需要使用Map或parameter等域对象,则建议使用Aware接口方式。
Ps:若一个一个Action类中有多个action方法都需要使用Map或parameter等域对象,则建议使用Aware接口方式。