action和Action
- action:代表一个strtus2请求
- Action类:能够处理strtus2请求的类
- 属性的名字必须遵循与JavaBean属性名相同的命名规则(属性的类型可以是任意类型,从字符串到非字符串即基本数据库类型之间的转换可以自动发生)
- 必须要有一个无参构造器
- 至少有一个供Strut2在执行这个action时调用的方法
- 同一个Action类可以包含多个action方法
- Struts2会为每一个HTTP请求创建一个新的Action实例,即Action不是单例的,是线程安全的
通过ActionContex获取Web资源
- 什么是web资源?
HttpServletRequest,HttpSession,ServletContext等原生的servlet API - 为什么访问Web资源
B/S的应用的controller中必然要访问web资源:向域对象中读写属性,读写cookie,获取realPath… - 如何访问?
- 和servlet API解耦的方式:只能访问有限的servlet API对象,且只能访问其有限的方法(读取请求参数,读写域对象属性,使session失效…)
- 使用ActionContext
- 实现XxxAware接口
- 选用的建议:若一个Action类中有多个action方法都需要使用域对象的Map或者parameters,建议使用实现XxxAware接口的方式
- 和servlet API 耦合的方式:可以访问更多的servlet API对象,且可以调用其原生的方法
- 使用ServletActionContext
- 实现ServletXxxAware接口
- 直接访问Servlet API将使Action和Servlet环境耦合在一起,测试时需要有servlet容器,不便于对Action的单元测试
- 和servlet API解耦的方式:只能访问有限的servlet API对象,且只能访问其有限的方法(读取请求参数,读写域对象属性,使session失效…)
- 通过常量配置Struts2的请求扩展名
<struts>
<!-- 配置struts2 可以受理请求的扩展名 -->
<constant name="struts.action.extension" value="action,do"></constant>
与Servlet API解耦的访问方式(使用ActionContext)
- 为了避免与Servlet API耦合在一起,方便Action做单元测试,Struts2对HttpServletRequest,HttpSession和ServletContext进行了封装,构造了三个Map对象来替代这三个对象,在Action中可以直接使用HttpServletRequest,HttpServletSession,ServletContext对应的Map对象来保存和取数据
1.index.jsp
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="testActionContext.action?name=james">test ActionContext</a>
<%
if(session.getAttribute("date") == null)
session.setAttribute("date", new Date());
//request.setAttribute("key", "value");
%>
</body>
</html>
2.show.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
applicationKey:${applicationScope.applicationKey }
<br><br>
sessionKey:${sessionScope.sessionKey }
<br><br>
requestKey:${requestScope.requestKey }
<br><br>
</body>
</html>
3.struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<package name="actionContext" extends="struts-default" >
<action name="testActionContext" class="cn.zc.cris.TestActionContextAction">
<result>/show.jsp</result>
</action>
</package>
</struts>
4.TestActionContextAction.java
public class TestActionContextAction {
@SuppressWarnings("unchecked")
public String execute() {
//0.获取ActionContext对象
//actionContext是Action的上下文对象,可以从中获取到当前Action需要的一切信息
ActionContext actionContext = ActionContext.getContext();
//1.获取application对应的map,并向其中添加一个属性
Map<String, Object> applicationMap = actionContext.getApplication();
applicationMap.put("applicationKey", "applicationValue");
//2.session
Map<String, Object> sessionMap = actionContext.getSession();
sessionMap.put("sessionKey", "sessionValue");
Object date = sessionMap.get("date");
System.out.println(date);
//session对应的map实际上是SessinMap类型的,强转后若调用其invalidate方法,可以使session失效!
if(sessionMap instanceof SessionMap) {
SessionMap<String, Object> sm = (SessionMap<String, Object>) sessionMap;
sm.invalidate();
System.out.println("session失效了");
}
//3.request*
//ActionContext中并没有直接获取getRequest方法来获取request对应的map
//需要手工的调用get方法并且传入request字符串参数来进行获取
Map<String, Object> requestMap = (Map<String, Object>) actionContext.get("request");
requestMap.put("requestKey", "requestValue");
//4.获取请求参数对应的map,并获取指定的值
//键:请求参数的名字;值:请求参数对应的Parameter,可以直接打印出来
HttpParameters parameters = actionContext.getParameters();
Parameter name = parameters.get("name");
System.out.println(name); //james
return "success";
}
}
与Servlet API解耦的访问方式(实现XxxAware接口)
1.TestAwareAction.java
public class TestAwareAction implements ApplicationAware{
private Map<String, Object> applicationMap = null;
public String execute() {
applicationMap.put("applicationKey2", "applicationValue2");
return "success";
}
//由struts2框架自动调用(注入模式)
@Override
public void setApplication(Map<String, Object> application) {
this.applicationMap = application;
}
}
2.struts.xml
<struts>
<package name="actionContext" extends="struts-default" >
<action name="testActionContext" class="cn.zc.cris.TestActionContextAction">
<result>/show.jsp</result>
</action>
<action name="testAware" class="cn.zc.cris.TestAwareAction">
<result>/aware.jsp</result>
</action>
</package>
</struts>
3.aware.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
applicationKey:${applicationScope.applicationKey2 }
<br><br>
</body>
</html>
与Servlet API耦合的访问方式(通过ServletActionContext)
public class TestServletActionContext {
public String execute() {
/**
* ServletActionContext:可以从中获取到当前Action对象需要的一切Servlet API相关的对象
* 常用的方法:
* 1. 获取HttpServletRequest:ServletActionContext.getRequest()
* 2. 获取HttpSession:ServletActionContext.getRequest().getSession()
* 3. 获取servletContext:ServletActionContext.getServletContext()
*
*/
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = request.getSession();
ServletContext servletContext = ServletActionContext.getServletContext();
System.out.println(request);
System.out.println(session);
System.out.println(servletContext);
return "success";
}
}
与Servlet API耦合的访问方式(通过实现servletXxxAware相关的接口的方式)
public class TestServletAwareAction implements ServletContextAware,ServletRequestAware,ServletResponseAware{
/**
* 通过实现servletXxxAware相关的接口的方式,可以由struts2注入需要的Servlet相关的对象
*
* ServletContextAware:注入ServletContext对象(常用)
* ServletRequestAware:注入HttpServletRequest对象(常用)
* ServletResponseAware:注入HttpServletResponse对象
*/
private ServletContext context;
@Override
public void setServletContext(ServletContext context) {
this.context = context;
}
public String execute() {
System.out.println(context);
return "success";
}
@Override
public void setServletResponse(HttpServletResponse response) {
}
@Override
public void setServletRequest(HttpServletRequest request) {
}
}
ActionSupport
1.ActionSupport是默认的Action类:若某个action节点没有配置class属性,则ActionSupport这个Strtus2提供的默认Action类将会默认执行其execute方法
<action name="testActionSupport" >
<result>/testActionSupport.jsp</result>
</action>
2.在手工完成字段验证,显示错误消息,国际化等情况下,推荐继承ActionSupport类(这个类作为适配器,已经为我们提供好了各个接口的默认实现)
public class TestActionSupport extends ActionSupport {
@Override
public String execute() throws Exception {
return SUCCESS;
}
}