Action 访问 Servlet API 的四种方式示例说明
Struts 2 的 Action 和 Servlet API 没有任何耦合,这是 Struts 2被称为「低侵入式」的一个改进,有利于测试。但在实际的 web 项目中,不可能不用到 web 对象,不可能不访问 Servlet API,如最常用的 request(HttpServletRequest), session(HttpSession), application(ServletContext) 等。如何操作这些对象,可以有如下四种方式:
1. 模拟——通过 ActionContext
参附件 Demo1
public class Demo1Action extends ActionSupport {
private Map request;
private Map session;
private Map application;
@Override
public String execute() throws Exception {
ActionContext context = ActionContext.getContext();
request = (Map) context.get("request");
session = context.getSession();
application = context.getApplication();
request.put("r1", "demo1, r1_value");
session.put("s1", "demo1, s1_value");
application.put("a1", "demo1, a1_value");
return SUCCESS;
}
}
2. 模拟——通过 XxxAware 接口
参附件 Demo2
在 org.apache.struts2.interceptor 包下有如下 Aware 接口
- ApplicationAware
- CookiesAware
- ParameterAware
- PrincipalAware
- RequestAware
- ServletRequestAware
- ServletResponseAware
- SessionAware
这里使用 RequestAware, SessionAware, ApplicationAware 这三个接口操作 request, session, application 对象。
public class Demo2Action extends ActionSupport implements RequestAware,
SessionAware, ApplicationAware {
private Map<String, Object> request;
private Map<String, Object> session;
private Map<String, Object> application;
@Override
public String execute() throws Exception {
request.put("r1", "demo2, r1_value");
session.put("s1", "demo2, s1_value");
application.put("a1", "demo2, a1_value");
return SUCCESS;
}
public void setApplication(Map<String, Object> application) {
this.application = application;
}
public void setSession(Map<String, Object> session) {
this.session = session;
}
public void setRequest(Map<String, Object> request) {
this.request = request;
}
}
注:这种方式可能是项目实践中用的比较多的那类。其中 request 一般无需这样操作,因为 Action 的成员变量会自动存放到 ValueStack 中,而 ValueStack 会存放到 request 对象中。
3. 访问真实的 Servlet 对象——通过 ServletActionContext 类
参附件 Demo3
public class Demo3Action extends ActionSupport {
@Override
public String execute() throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = ServletActionContext.getRequest().getSession();
ServletContext application = ServletActionContext.getServletContext();
request.setAttribute("r1", "demo3, r1_value");
session.setAttribute("s1", "demo3, s1_value");
application.setAttribute("a1", "demo3, a1_value");
return super.execute();
}
}
4. 访问真实的 Servlet 对象——通过 ServletRequestAware 接口
参附件 Demo4
通过 ServletRequestAware 接口也可以直接访问 Servlet API
public class Demo4Action extends ActionSupport implements ServletRequestAware {
HttpServletRequest request;
@Override
public String execute() throws Exception {
ServletContext application = ServletActionContext.getServletContext();
request.setAttribute("r1", "demo4, r1_value");
request.getSession().setAttribute("s1", "demo4, s1_value");
request.getServletContext().setAttribute("a1", "demo4, a1_value");
return super.execute();
}
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
}
注意,还可以用 ServletContextAware 这个接口,这里不再示例。
示例代码说明
以上代码在对应的页面代码片段是一样的:
request:
<s:property value="#request.r1"/>
or
<%=request.getAttribute("r1") %>
session:
<s:property value="#session.s1"/>
or
<%=session.getAttribute("s1") %>
application:
<s:property value="#application.a1"/>
or
<%=application.getAttribute("a1") %>
完整的示例代码,参附件。
总结和问题
总结。以上 Demo2 和 Demo4 体现了 DI 的思想:三个对象依赖于 Struts 2 框架初始化和注入;也体现了 IoC 的思想:对三个对象的控制,传统方式是程序员自己,现在控制权交给 Struts 2 框架了。
问题。为什么要提供这么多中方式访问 Servlet API?