Action类
普通的 Java 类, 可以有属性和方法, 同时必须遵守一些规则。
遵循规则
- 属性的名字必须遵守与 JavaBeans 属性名相同的命名规则. 属性的类型可以是任意类型. 从字符串到非字符串(基本数据库类型)之间的数据转换可以自动发生
- 必须有一个不带参的构造器
- 至少有一个供 struts 在执行这个 action 时调用的方法
- 同一个 Action 类可以包含多个 action 方法
- Struts2 会为每一个 HTTP 请求创建一个新的 Action 实例
访问 web 资源
与 Servlet API 解耦的访问方式
为了避免与 Servlet API 耦合在一起, 方便 Action 做单元测试, Struts2 对 HttpServletRequest, HttpSession 和 ServletContext 进行了封装, 构造了 3 个 Map 对象来替代这 3 个对象, 在 Action 中可以直接使用 HttpServletRequest, HttpServletSession, ServletContext 对应的 Map 对象来保存和读取数据
通过 ActionContext 访问 Web 资源
ActionContext 是 Action 执行的上下文对象, 在 ActionContext 中保存了 Action 执行所需要的所有对象, 包括 parameters, request, session, application 等.
ActionContext actionContext=ActionContext.getContext();
- 获取 HttpSession 对应的 Map 对象:
public Map getSession()
//action类中的放入session
Map<String,Object>sessionMap=actionContext.getSession();
sessionMap.put("sessionKey", "sessionValue");
<!--获取session-->
session:${sessionScope.sessionKey}
- 获取 ServletContext 对应的 Map 对象:
public Map getApplication()
<!--页面调用之前加入属性-->
<%
if(application.getAttribute("date")==null)
application.setAttribute("date",new Date());
%>
//action类中的方法获取map
Map<String,Object> appliactionMap=actionContext.getApplication();
appliactionMap.put("applilactionKey", "applicationValue");
Object date=appliactionMap.get("date");
System.out.println("date:"+date);
<!--在jsp中获取存入的数据-->
application:${applicationScope.applilactionKey}
- 获取请求参数对应的 Map 对象:
public Map getParameters()
<a href="TestActionContext.action?name=atguigu">Test ActionContext</a>
请求参数的名字, 值: 请求参数的值对应的字符串数组
注意: 1. getParameters 的返回值为在 Map<String, Object>, 而不是 Map<String, String[]>
2. parameters 这个 Map 只能读, 不能写入数据, 如果写入, 但不出错, 但也不起作用!
//action类中的方法获取map
Map<String,Object>parameters=actionContext.getParameters();
System.out.println(((String[])parameters.get("name"))[0]);
如果是在Struts2-5中,读取代码如下:
Map<String, Parameter> parameters=actionContext.getParameters();
System.out.println(parameters.get(productName).getMultipleValues());
- 获取 HttpServletRequest 对应的 Map 对象:
public Object get(Object key): ActionContext 类中没有提供类似 getRequest() 这样的方法来获取 HttpServletRequest 对应的 Map 对象. 要得到 HttpServletRequest 对应的 Map 对象, 可以通过为 get() 方法传递 “request” 参数实现
//action类中的方法获取map
Map<String,Object>requestMap=(Map<String, Object>) actionContext.get("request");
requestMap.put("requestKey", "requestValue");
<!--在jsp中获取存入的数据-->
request:${requestScope.requestKey}
通过实现 Aware 接口访问 Web 资源
通过接口实现。接口在包org.apache.struts2.interceptor下面。
包含的接口如下:
ApplicatioinAware
通过继承ApplicatioinAware来实现application的传值和访问。
action类的实例代码如下:
package com.atguigu.struts2.action;
import java.util.Map;
import org.apache.struts2.interceptor.ApplicationAware;
public class TestAwareAction implements ApplicationAware {
public String execute() {
application.put("applicationKey2", "applicationValue2");
System.out.println(application.get("date"));
return "success";
}
private Map<String,Object> application;
@Override
public void setApplication(Map<String, Object> arg0) {
// TODO Auto-generated method stub
this.application=arg0;
}
struts.xml文件代码如下:
<action name="TestAwareAction" class="com.atguigu.struts2.action.TestAwareAction">
<result>/test-aware.jsp</result>
</action>
原始jsp传入data
<a href="TestAwareAction.action">Test Aware</a>
<%
if(application.getAttribute("date")==null)
application.setAttribute("date",new Date());
%>
test-aware.jsp页面获取数据代码如下:
application:${applicationScope.applicationKey2}
ParameterAware
RequestAware
SessionAware
实例代码如下:
1.实现三个接口
package com.atguigu.struts2.action;
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,ParameterAware,RequestAware,SessionAware{
public String execute() {
application.put("applicationKey2", "applicationValue2");
System.out.println(application.get("date"));
session.put("sessionKey2", "sessionValue2");
request.put("requestKey2", "requestValue2");
System.out.println((parameters.get("name"))[0]);
return "success";
}
private Map<String,Object> application;
private Map<String,String[]> parameters;
private Map<String,Object> request;
private Map<String,Object> session;
@Override
public void setApplication(Map<String, Object> application) {
this.application=application;
}
@Override
public void setSession(Map<String, Object> session) {
this.session=session;
}
@Override
public void setRequest(Map<String, Object> request) {
this.request=request;
}
@Override
public void setParameters(Map<String, String[]> parameters) {
this.parameters=parameters;
}
2.在配置文件中进行文件配置
<action name="TestAwareAction" class="com.atguigu.struts2.action.TestAwareAction">
<result>/test-aware.jsp</result>
</action>
3.传值页面配置如下:
<a href="TestAwareAction.action?name=atguigu">Test Aware</a>
4.返回获取结果页面如下:
<h4>Test aware page</h4>
application:${applicationScope.applicationKey2}
<br><br>
session:${sessionScope.sessionKey2}
<br><br>
request:${requestScope.requestKey2}
session 对应的 Map 实际上是 SessionMap 类型的! 强转后若调用其 invalidate() 方法, 可以使其 session 失效!
if(sessionMap instanceof SessionMap)
{
SessionMap sm=(SessionMap)sessionMap;
sm.invalidate();
}
选用的建议
若一个 Action 类中有多个 action 方法, 且多个方法都需要使用域对象的 Map 或 parameters, 则建议使用Aware 接口的方式。
与 Servlet API 耦合的访问方式
使用ServletActionContext和页面实现交互
直接获取 HttpServletRequest 对象:
- ServletActionContext.getRequest()
直接获取 HttpSession 对象 - ServletActionContext.getRequest().getSession()
直接获取 ServletContext 对象 - ServletActionContext.getServletContext()
public class TestServletActionContextAction {
public String execute()
{
HttpServletRequest request=ServletActionContext.getRequest();
HttpSession session=ServletActionContext.getRequest().getSession();
ServletContext servletContext=ServletActionContext.getServletContext();
System.out.println("test....");
return "success";
}
}
通过实现 ServletRequestAware, ServletContextAware 等接口的方式
ServletRequestAware
ServletContextAware
ServletResponseAware
实例代码:
public class TestServletAwareActioin implements ServletRequestAware,
ServletContextAware,ServletResponseAware{
@Override
public void setServletContext(ServletContext context) {
// TODO Auto-generated method stub
this.context=context;
}
private ServletContext context;
@Override
public void setServletRequest(HttpServletRequest request) {
// TODO Auto-generated method stub
}
@Override
public void setServletResponse(HttpServletResponse response) {
// TODO Auto-generated method stub
}
public String execute()
{
System.out.println("ServletContext"+context);
return "success";
}
}