1.概述
1.Action:能够处理Struts2请求的类
2.Action类的属性的名字必须遵守与JavaBeans属性名相同的命名规则
属性的类型可以是任意类型,从字符串到非字符串(基本数据库类型)之间的数据转换可以自动发生
3.必须有一个不带参的构造器:通过反射创建实例
4.至少有一个供Struts在执行这个action时调用的方法
5.同一个Action类可以包含多个action方法
6.Struts2会为每一个HTTP请求创建一个新的Action实例,即Action不是单例的,不会有线程安全问题。
2.在Action中访问WEB资源
1.WEB资源
WEB资源是指:HttpServletRequest,HttpSession,ServletContext等原生的Servlet API
2.为何要访问WEB资源
B\S的应用的Controller中必要需要访问WEB资源:向域对象中读写属性,读写Cookie,获取realPath…
3.访问的方法
1.和Servlet API解耦的方式
只能访问有限的Servlet API对象,且只能访问其优先的方法(读取请求参数,读写域对象的属性,使session失效等等)。
1.使用ActionContext
2.实现XxxAware接口
2.和Servlet API耦合的方式
可以访问更多的Servlet API对象,且可以调用其原生的方法
1.使用ServletActionContext
2.实现ServletXxxAware接口
4.通过和Servlet API解耦的方式访问WEB资源
1.使用ActionContext来获取WEB资源
1.关于ActionContext
ActionContext是Action的上下文对象,可以从中获取到当前Action需要的一切信息
可以获取到封装的application,session,request等等
2.使用方法(以application为例)
获取的方法:通过调用ActionContext对象的getApplication()方法来获取application对象的Map对象
3.Demo:
struts.xml中的配置:
<struts>
<package name="default" extends="struts-default">
<action name="TestActionContext" class="struts2.action.TestActionContextAction" method="execute">
<result>/test-actionContext.jsp</result>
</action>
</package>
</struts>
TestActionContextAction.java:
public class TestActionContextAction {
public String execute(){
//获取ActionContext对象
ActionContext actionContext = ActionContext.getContext();
//1.获取Application对应的Map,并向其中添加一个属性
Map <String,Object> applicationMap = actionContext.getApplication();
//设置属性
applicationMap.put("applicationKey","applicationValue");
//获取属性
Object date = applicationMap.get("date");
System.out.println(date);
//2.获取session对应的Map
Map<String,Object> sessionMap = actionContext.getSession();
sessionMap.put("sessionKey","sessionValue");
//3.获取request对应的Map
//ActionContext中没有提供getRequest方法来获取request对应的Map
//需要手工调用get()方法,传入request字符串来获取
Map<String,Object> requestMap = (Map < String, Object >) actionContext.get("request");
requestMap.put("requestKey","requestValue");
//4.获取封装的请求请求参数,并获取指定的参数值
//只能读,不能写入数据
HttpParameters parameters = actionContext.getParameters();
System.out.println(parameters.get("name"));
return "success";
}
}
index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<a href="TestActionContext.action?name=cerr">Test</a>
<%
if(application.getAttribute("date") == null){
application.setAttribute("date",new Date());
}
%>
</body>
</html>
test-actionContext.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h4>Test ActionContext Page</h4>
<!-- 设置属性后可以这么获取属性 -->
application : ${applicationScope.applicationKey}
<br><br>
session:${sessionScope.sessionKey}
<br><br>
request:${requestScope.requestKey}
</body>
</html>
2.使用Aware接口来获取WEB资源
通过实现ApplicationAware, SessionAware, RequestAware等接口来实现.
Demo:
struts.xml:
<struts>
<package name="default" extends="struts-default">
<action name="TestAware" class="struts2.action.TestAwareAction" >
<result>/test-aware.jsp</result>
</action>
</package>
</struts>
TestAwareAction.java:
public class TestAwareAction implements ApplicationAware, SessionAware, RequestAware {
private Map<String,Object> applicationMap;
private Map<String,Object> sessionMap;
private Map<String,Object> requestMap;
private Map < String, String[] > parameterMap;
public String execute(){
//1.向application中加入一个属性
applicationMap.put("applicationKey2","applicationValue2");
//2.从application中读取一个属性
System.out.println(applicationMap.get("date"));
//session:
sessionMap.put("sessionKey2","sessionValue2");
//request:
requestMap.put("requestKey2","requestValue2");
return "success";
}
@Override
public void setApplication(Map < String, Object > map) {
this.applicationMap = map;
}
@Override
public void setRequest(Map < String, Object > map) {
requestMap = map;
}
@Override
public void setSession(Map < String, Object > map) {
sessionMap = map;
}
}
test-aware.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h4>Test Aware Page</h4>
application : ${applicationScope.applicationKey2}
<br><br>
session : ${sessionScope.sessionKey2}
<br><br>
request : ${requestScope.requestKey2}
<br><br>
</body>
</html>
3.选用的建议
如果一个Action类中有多个action方法,且多个方法都需要使用域对象的Map或parameters,则建议使用实现Aware接口的方式
4.注意
session对应的Map实际上是SessionMap类型的,强转后若调用其invalidate()方法,可以使其session失效.
5.通过与Servlet耦合的方式访问WEB资源
1.通过ServletActionContext
1.ServletActionContext
可以从中获取到当前Action对象需要的一切Servlet API相关的对象
2.获取HttpServletRequest对象
ServletActionContext.getRequest()
3.获取HttpSession对象
ServletActionContext.getRequest().getSession()
4.获取ServletContext对象
ServletActionContext.getServletContext()
5.Demo
public class TestServletActionContextAction {
public String execute(){
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = ServletActionContext.getRequest().getSession();
ServletContext servletContext = ServletActionContext.getServletContext();
System.out.println("execute");
return "success";
}
}
2.通过实现SerlvetRequestAware,ServletContextAware等接口的方式
1.通过实现ServletXxxAware接口的方式可以由Struts2注入需要的Servlet相关的对象
ServletRequestAware:注入HttpServletRequest对象
ServletContextAware:注入ServletContext对象
ServletResponseAware:注入HttpServletResponse
3.关于Struts2请求的扩展名问题
在struts2的struts2-core-2.5.20.jar中的org.apache.struts2包下的default.properties中配置了Struts2应用的一些常量.
struts.action.extension定义了当前Struts2应用可以接受的请求的扩展名
可以在struts.xml文件中以常量配置的方式修改default.properties所配置的常量,默认的请求扩展名为action和空
配置的Demo:
<struts>
<!-- 配置Struts可以受理的请求的扩展名 -->
<constant name="struts.action.extension" value="action,do"></constant>
<package name="default" extends="struts-default">
<action name="TestServletAware" class="struts2.action.TestServletAwareAction" >
<result>/success.jsp</result>
</action>
</package>
</struts>
4.ActionSupport
ActionSupport是默认的Action类:若某个action节点没有配置class属性,则ActionSupport是待执行的Action类,而execute方法即为要默认执行的action方法
<action name="TestActionSupport">
<result>/testActionSupport.jsp</result>
</action>
等同于
<action name="TestActionSupport" class="com.opensymphony.xwork2.ActionSupport" method="execute">
<result>/testActionSupport.jsp</result>
</action>
在手工完成字段验证,显示错误信息,国际化等情况下,推荐继承ActionSupport.