Struts2 与 Servlet API 解耦,耦合的访问方式

与Servlet API解耦的访问方式

为了避免与Servlet API耦合在一起,方便Action类做单元测试,Struts2对HttpServletRequest、HttpSession和ServletContext进行了封装,构造了三个Map对象来替代这三种对象,在Action中,直接使用HttpServletRequest、HttpSession、ServletContext对应的Map对象来保存和读取数据。要获得这三个Map对象,可以使用com.opensymphony.xwork2.ActionContext类

ActionContext - 请求上下文 。就是struts2封装的request.包含了request,session,application上面这三个都是Map

1
2
3
4
5
6
7
8
9
10
//导包
import com.opensymphony.xwork2.ActionContext;
import java.util.Map;
//常量
import static org.apache.struts2.StrutsStatics.HTTP_REQUEST;
import static org.apache.struts2.StrutsStatics.HTTP_RESPONSE;

Map<String, Object> session = ActionContext.getContext().getSession();
Map<String, Object> request = (Map<String, Object>) ActionContext.getContext().get(HTTP_REQUEST);
Map<String, Object> response = (Map<String, Object>) ActionContext.getContext().get(HTTP_RESPONSE);

与Servlet API耦合的访问方式

直接访问 Servlet API将使Action类与Servlet API耦合在一起,Servlet API对象均由Servlet容器来构造,与这些对象绑定在一起,测试过程中就必须有Servlet容器,这样不便于Action类的测试,但有时候,确实需要访问这些对象,Struts2同样提供了直接访问ServletAPI对象的方式

要直接获取Servlet API对象可以使用org.apache.struts2.ServletActionContext类,该类是ActionContext类的子类

1
2
3
4
5
6
7
8
9
import org.apache.struts2.ServletActionContext;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public HttpServletRequest request = ServletActionContext.getRequest();
public HttpServletResponse response = ServletActionContext.getResponse();
public HttpSession session = request.getSession(true);

在实际开发中,可能多个页面需要得到这三个对象,为了避免代码冗余。创建一个 ActionBase 类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package cn.action;

import cn.pojo.User;
import cn.util.Constants;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class ActionBase extends ActionSupport {
public HttpServletRequest request = ServletActionContext.getRequest();
public HttpServletResponse response = ServletActionContext.getResponse();
public HttpSession session = request.getSession(true);

public ActionBase() {
//避免ajax提取数据中文乱码
response.setContentType("text/html;charset=UTF-8");
}

public User getSessionUser() {
Object o = session.getAttribute(Constants.USER_SESSION);
if (null == o)
return null;
return (User) o;
}
}

USER_SESSION 为自定义的常量工具类 Constants
User 为用户对象实体类

每个自定义的 action 类,都需要继承 ActionSupportActionBase 继承 ActionSupport 并新增想要的属性和方法以便需要继承的 ActionSupport 的类 直接继承 ActionBase

新增属性

上面代码可见新增了 request response session 的属性 这样就实现自己新增的属性以及 ActionSupport 的属性

新增方法

上面代码可见新增了 getSessionUser 的方法 这样就实现自己新增的方法以及 ActionSupport 的方法,以便自己可以直接提取存在会话的用户对象 User