Struts2 相比 Struts1 而言,Struts2的Action并未直接与任何Servlet API耦合,这是Struts2的一个改良之处,使得 Action 可以脱离 Web 容器进行测试;另外因为Action是一个普通的Java类,而不是一个Servlet类,完全脱离于Web容器,所以我们就能够更加方便地对Control层进行合理的层次设计,从而抽象出许多公共的逻辑,并将这些逻辑脱离出Action对象本身。
事实上,Struts2也正是这么做的,无论是Interceptor,还是Result,其实都是抽象出了Action中公共的逻辑部分,将他们放到了Action的外面,从而更加简化了Action的开发。
但是在开发过程中,往往也需要在Action里直接获取请求(Request)或会话 (Session)的一些信息,甚至需要直接对JavaServlet Http的HttpServletRequest,HttpServletResponse对象进行操作,下面介绍三种方式,可以使Action能够访问Servlet API。
1、通过ActionContext访问Servlet API
此种方式没有侵入性,操作servlet API的过程是透明的。
//将登录信息设置到session中
ActionContext.getContext().getSession().put("user", username);
//采用如下方式访问request对象
ActionContext.getContext().put("user", username);
//采用如下方式访问application对象
ActionContext.getContext().getApplication().put(key, value)
//通过request.getParameter()取得数据
String username = ActionContext.getContext().getParameters().get("username");
2、 通过实现装配接口,完成对Servlet API的访问,有侵入性
- 通过实现接口ServletRequestAware取得HttpServletRequest对象
- 通过实现接口 ServletResponseAware取得HttpServletResponse对象
- 通过实现接口ServletContextAware取得ServletContext对象(工具类)
代码示例
public class LoginAction implements Action, ServletRequestAware {
private String username;
private String password;
private HttpServletRequest request;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String execute() throws Exception {
if ("admin".equals(username) && "admin".equals(password)) {
request.getSession().setAttribute("user", username);
return SUCCESS;
} else {
return ERROR;
}
}
@Override
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
}
3、通过ServletActionContext提供的静态方法取得Servlet API,有侵入性
ServletActionContext的几个静态方法:
- getPageContext();
- getRequest();
- getResponse();
- getServletContext();
代码示例
ServletActionContext.getRequest().getSession()
.setAttribute("user", username);
小结
就这三种访问方式来说,通过ActionContext访问Servlet API,这种方式没有侵入性,原理是将其放入到map中,不会直接操作servlet API,但是缺点是不能访问HttpServletResponse对象;第二种实现接口方式比较繁琐,一般不会采用;第三种通过ServletActionContext静态方法方式访问比较简单,不考虑侵入性的话,这种方式是应用最广泛的。