在传统的Web'开发中,经常会用到ServletAPI中的HttpServletRequest、HttpSesion和HttpServletContext。Struts 2框架让我们可以直接访问和设置action及模型对象的数据,这降低了对HttpServletRequest对象的使用需求,但在某些应用中,我们可能会需要在action中去访问HttpServletRequest对象以及其他两种对象,例如,用户登录成功后,我们应该将用户信息保存到Session中。
Struts 2提供了多种方式来访问上述的三种对象,归结起来,可以划分为两大类:与Servlet API解耦的访问方式和与Servlet API耦合的访问方式。
与Servlet API解耦的访问方式(只能访问有限的Servlet API 对象,且只能访问其有限的方法)
使用ActionContext
ActionContext 是 Action 执行的上下文对象, 在ActionContext 中保存了 Action执行所需要的所有对象, 包括parameters, request, session, application 等。
获取 HttpSession 对应的 Map 对象: public Map getSession()。
获取 ServletContext 对应的 Map 对象: public Map getApplication()。
实现xxxAware接口获取请求参数对应的 Map 对象: public Map getParameters()。
获取 HttpServletRequest对应的 Map 对象:
public Objectget(Object key): ActionContext 类中没有提供类似 getRequest() 这样的方法来获取 HttpServletRequest 对应的 Map 对象. 要得到 HttpServletRequest 对应的
Map 对象, 可以通过为 get() 方法传递“request”参数实现。
二者比较:Action类通过实现某些特定的接口,让struts2框架在运行时向Action示例注入parameters,request,session,application对应的Map对象。
org.apache.struts2.interceptor.ApplicationAware;
org.apache.struts2.interceptor.parameterAware;
org.apache.struts2.interceptor.RequestAware;
org.apache.struts2.interceptor.SessionAware;
与Servlet API耦合的访问方式(可以访问更多的Servlet API对象,且可以调用其原生的方法)若一个Action类中有多个action方法,且多个方法都需要使用域对象的Map或parameters,建议使用Aware接口的方式。
代码实现:
web.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>struts2-3</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
接下来我们就可以编写我们的动作(Action)类:
import java.util.Map; import com.opensymphony.xwork2.ActionContext; public class TestActionContextAction { public String execute() { ActionContext actionContext = ActionContext.getContext(); Map<String,Object> applicationMap = actionContext.getApplication(); applicationMap.put("applicationKey", "applicationValue"); Object date = applicationMap.get("date"); System.out.println(date); Map<String, Object> sessionMap = actionContext.getSession(); sessionMap.put("sessionKey", "sessionValue"); Map<String,Object> requestMap = (Map<String,Object>)actionContext.get("request"); requestMap.put("requestKey", "requestValue"); Map<String,Object> parameters = actionContext.getParameters(); System.out.println(((String[])parameters.get("name"))[0]); return "success"; } }
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 { public String execute() { //向application中加入一个属性 applicationMap.put("applicationKey2", "applicationValue2"); //从application中读取一个属性 System.out.println(applicationMap.get("date")); sessionMap.put("sessionKey2", "sessionValue2"); requestMap.put("requestKey2", "requestValue2"); System.out.println(parametersMap.get("name2")[0]); return "success"; } private Map<String,Object> applicationMap; private Map<String,Object> sessionMap; private Map<String,Object> requestMap; private Map<String,String[]> parametersMap; public void setApplication(Map<String,Object> applicationMap) { this.applicationMap = applicationMap; } public void setSession(Map<String,Object> sessionMap) { this.sessionMap = sessionMap; } public void setRequest(Map<String,Object> requestMap) { this.requestMap = requestMap; } public void setParameters(Map<String,String[]> parametersMap) { this.parametersMap = parametersMap; } }
struts.xml文件如下:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <!-- Add packages here --> <constant name="struts.devMode" value="true" /> <package name="default" namespace="/" extends="struts-default"> <action name="TestActionContext" class="com.sdust.www.TestActionContextAction" method="execute"> <result name="success"> /WEB-INF/pages/testActionContext.jsp </result> </action> <action name="TestAwareAction" class="com.sdust.www.TestAwareAction" method="execute"> <result name="success"> /WEB-INF/pages/testAware.jsp </result> </action> </package> </struts>
index.jsp文件:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <a href="TestActionContext.action?name=admin">Test ActionContext</a><br><br> <a href="TestAwareAction.action?name2=admin2">Test Aware</a><br><br> <% if(application.getAttribute("date") == null) application.setAttribute("date", new Date()); %> </body> </html>
testActionContext.jsp文件:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'testActionContext.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <h1>Test ActionContext</h1> application : ${applicationScope.applicationKey}<br><br> session : ${sessionScope.sessionKey} <br><br> request : ${requestScope.requestKey } <br><br> </body> </html>
testAware.jsp
<span style="color:#009900;"><%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'testAware.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <h1>Test Aware Page</h1> application : ${applicationScope.applicationKey2} <br><br> session : ${sessionScope.sessionKey2} <br><br> request : ${requestScope.requestKey2} <br><br> </body> </html></span>
使用ServletActionContext直接访问 Servlet API 将使 Action 与 Servlet 环境耦合在一起, 测试时需要有Servlet 容器,不便于对 Action 的单元测试。
实现ServletXxxContext接口可以从ServletActionContext中获取Action对象需要的一切与Servlet API相关的对象
常用方法:
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = ServletActionContext.getRequest().getSession();
ServletContext servletContext = ServletActionContext.getServletContext();
通过实现ServletXxxAware接口的方式由struts2注入祖耀的Servlet的相关对象。
ServletRequestAware:注入HttpServletRequest对象
ServletContextAware:注入ServletContext对象
ServletResponseAware:注入HttpServletResponse对象