action VS Action 类
1. action:代表一个 Struts2 的请求。
2. Action类:能够处理 Struts2 请求的类。
2.1 属性的名字必须遵守与 JavaBeans 属性名相同的命名规则。
2.2 属性的类型可以是任意类型,从字符串到非字符串(基本数据库类型)之间的数据转换可以自动发生。
2.3 必须有一个不带参的构造器:通过反射创建实例 。
2.4 至少有一个供 struts 在执行这个 action 时调用的方法。
2.5 同一个 Action 类可以包含多个 action 方法。
2.6 Struts2 会为每一个 HTTP 请求创建一个新的 Action 实例,即 Action 不是单例的, 是线程安全的.
2.7 Struts2会把请求中的参数通过对应的set方法自动设置到Action的属性中。
在Action中访问Web资源
1. 什么是 WEB 资源 ?
HttpServletRequest, HttpSession, ServletContext 等原生的 Servlet API。
2. 为什么访问 WEB 资源?
B\S 的应用的 Controller 中必然需要访问 WEB 资源,如向域对象中读写属性,读写 Cookie,获取 realPath等等。
3. 如何访问 ?
3.1 和 Servlet API 解耦的方式:只能访问有限的 Servlet API 对象,且只能访问其有限的方法(读取请求参数,读写域对象的属性,使 session 失效等)。
> 使用 ActionContext
> 实现 XxxAware 接口
> 选用的建议: 若一个 Action 类中有多个 action 方法, 且多个方法都需要使用域对象的 Map 或 parameters, 则建议使用
Aware 接口的方式
> session 对应的 Map 实际上是 SessionMap 类型的! 强转后若调用其 invalidate() 方法, 可以使其 session 失效!
3.2 和 Servlet API 耦合的方式:可以访问更多的 Servlet API 对象,且可以调用其原生的方法。
> 使用 ServletActionContext
> 实现 ServletXxxAware 接口
示例
1. 新建工程org.rabbitx.web.struts2.action
2. 添加需要的jar包
3. 配置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_2_5.xsd" id="WebApp_ID" version="2.5"> <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>*.action</url-pattern> </filter-mapping> </web-app>
4. 添加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>在Action中访问Web资源</title> </head> <body> <!-- 在请求中添加数据 --> <%request.setAttribute("requestKey", "requestValue"); %> <!-- 在会话中添加数据 --> <%session.setAttribute("sessionKey", "sessionValue"); %> <!-- 在应用中添加数据 --> <%application.setAttribute("applicationKey", "applicationValue"); %> <!-- 在请求中添加参数 --> <a href="actionContext.action?id=10001&name=Jack&name=Rose">使用 ActionContext访问Web资源</a><br/><br/> <!-- 在请求中添加参数 --> <a href="aware.action?id=10001&name=Jack&name=Rose">使用实现ApplicationAware, SessionAware,RequestAware, ParameterAware的方式访问Web资源</a><br/><br/> <a href="servletActionContext.action?id=10001&name=Jack&name=Rose">使用 ServletActionContext访问原生Web资源</a><br/><br/> <a href="servletAware.action?id=10001&name=Jack&name=Rose">使用实现ServletRequestAware,ServletContextAware的方式访问原生Web资源</a><br/><br/> </body> </html>
<%@ 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>在Action中访问Web资源</title> </head> <body> <h1>JSP代码方式获取数据</h1> parameter(id):<%=request.getParameter("id") %><br/> parameter(name):<%=request.getParameterValues("name").length %><br/> request: <%=request.getAttribute("requestKey")%><br/> session: <%=session.getAttribute("sessionKey")%><br/> application: <%=application.getAttribute("applicationKey")%><br/> <hr/> new-request: <%=request.getAttribute("newRequestKey")%><br/> new-session: <%=session.getAttribute("newSessionKey")%><br/> new-application: <%=application.getAttribute("newApplicationKey")%><br/> <h1>EL表达式方式获取</h1> parameter(id):${parameters.id }<br/> parameter(name):${parameters.name }<br/> request: ${requestScope.requestKey }<br/> session: ${sessionScope.sessionKey }<br/> application: ${applicationScope.applicationKey }<br/> <hr/> <!-- 获取Action中添加到请求,会话和应用中的新数据 --> new-request: ${requestScope.newRequestKey }<br/> new-session: ${sessionScope.newSessionKey}<br/> new-application: ${applicationScope.newApplicationKey }<br/> <hr/> <a href="index.jsp" style="float:right;">返回首页</a> </body> </html>
5. 添加Action
package org.rabbitx.web.struts2.action;
import java.util.Map;
import org.apache.struts2.dispatcher.SessionMap;
import com.opensymphony.xwork2.ActionContext;
/**
* 使用 ActionContext访问Web资源
*
* @author RabbitX
*
*/
public class TestActionContextAction {
private String id;
private String[] name;
@SuppressWarnings({ "unchecked", "rawtypes" })
public String execute()
{
//获取 ActionContext对象:ActionContext是 Action的上下文对象,可以从中获取到当前Action需要的一切信息
ActionContext actionContext = ActionContext.getContext();
//获取 application对应的 Map, 可添加/获取属性
//通过调用 ActionContext对象的 getApplication()方法来获取 application 对象的 Map对象
Map<String,Object> applicationMap = actionContext.getApplication();
//获取 session 对应的 Map,可添加/获取属性
//通过调用 ActionContext对象的 getSession()方法来获取 application 对象的 Map对象
Map<String,Object> sessionMap = actionContext.getSession();
//session 对应的 Map 实际上是 SessionMap 类型的! 强转后若调用其 invalidate() 方法, 可以使其 session 失效!
if(sessionMap instanceof SessionMap){
SessionMap sm = (SessionMap) sessionMap;
sm.invalidate();
System.out.println("session 失效了. ");
}
//request*
//ActionContext中并没有提供 getRequest方法来获取 request对应的 Map
//需要手工调用 get()方法, 传入request字符串来获取
Map<String,Object> requestMap = (Map<String,Object>)actionContext.get("request");
//从请求中获取页面中添加到应用,会话和请求中的数据
//从应用中获取数据
System.out.println(applicationMap.get("applicationKey"));
//从会话中获取数据
System.out.println(sessionMap.get("sessionKey"));
//从请求中获取数据
//此方式无法获取请求中的数据,不知为何?
System.out.println(requestMap.get("requestKey"));//返回null
//从请求中获取参数数据
//Struts2自动把参数注入到此Action中
System.out.println(getId());
System.out.println(getName().length);
//获取请求参数对应的 Map, 并获取指定的参数值.
//键: 请求参数的名字
//值: 请求参数的值对应的字符串数组
//注意:1. getParameters 的返回值为在 Map<String, Object>, 而不是 Map<String, String[]>
// 2. parameters 这个 Map 只能读, 不能写入数据, 如果写入,不出错, 但不起作用!
Map<String, Object> parameters = actionContext.getParameters();
System.out.println(((String[])parameters.get("name"))[0]);
//在应用中添加数据
applicationMap.put("newApplicationKey", "newApplicationValue");
//在会话中添加数据
sessionMap.put("newSessionKey", "newSessionValue");
//在请求中添加数据
requestMap.put("newRequestKey", "newRequestValue");
return "success";
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String[] getName() {
return name;
}
public void setName(String[] name) {
this.name = name;
}
}
package org.rabbitx.web.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;
/**
* 使用实现ApplicationAware, SessionAware,RequestAware, ParameterAware的方式访问Web资源
*
* @author RabbitX
*
*/
public class TestAwareAction implements ApplicationAware, SessionAware,RequestAware, ParameterAware {
private Map<String, Object> application;
private Map<String, Object> session;
private Map<String, Object> request;
private Map<String, String[]> parameters;
private String id;
private String[] name;
@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;
}
public String execute()
{
//从请求中获取页面中添加到应用,会话和请求中的数据
//从应用中获取数据
System.out.println(application.get("applicationKey"));
//从会话中获取数据
System.out.println(session.get("sessionKey"));
//从请求中获取数据
//此方式无法获取请求中的数据,不知为何?
System.out.println(request.get("requestKey"));//返回null
//从请求中获取参数数据
//Struts2自动把参数注入到此Action中
System.out.println(getId());
System.out.println(getName().length);
//获取请求参数对应的 Map, 并获取指定的参数值.
//键: 请求参数的名字
//值: 请求参数的值对应的字符串数组
//注意:1. getParameters 的返回值为在 Map<String, Object>, 而不是 Map<String, String[]>
// 2. parameters 这个 Map 只能读, 不能写入数据, 如果写入,不出错, 但不起作用!
System.out.println(((String[])parameters.get("name"))[0]);
//在应用中添加数据
application.put("newApplicationKey", "newApplicationValue");
//在会话中添加数据
session.put("newSessionKey", "newSessionValue");
//在请求中添加数据
request.put("newRequestKey", "newRequestValue");
System.out.println(getApplicationKey());//返回null
System.out.println(getSessionKey());//返回null
System.out.println(getRequestKey());//返回null
return "success";
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String[] getName() {
return name;
}
public void setName(String[] name) {
this.name = name;
}
private String applicationKey;
private String sessionKey;
private String requestKey;
public String getApplicationKey() {
return applicationKey;
}
public void setApplicationKey(String applicationKey) {
this.applicationKey = applicationKey;
}
public String getSessionKey() {
return sessionKey;
}
public void setSessionKey(String sessionKey) {
this.sessionKey = sessionKey;
}
public String getRequestKey() {
return requestKey;
}
public void setRequestKey(String requestKey) {
this.requestKey = requestKey;
}
public Map<String, Object> getApplication() {
return application;
}
public Map<String, Object> getSession() {
return session;
}
public Map<String, Object> getRequest() {
return request;
}
public Map<String, String[]> getParameters() {
return parameters;
}
}
package org.rabbitx.web.struts2.action;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
/**
* 使用 ServletActionContext访问原生Web资源
*
* @author RabbitX
*
*/
public class TestServletActionContextAction{
private String id;
private String[] name;
public String execute()
{
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = request.getSession();
ServletContext application = ServletActionContext.getServletContext();
//从请求中获取页面中添加到应用,会话和请求中的数据
//从应用中获取数据
System.out.println(application.getAttribute("applicationKey"));
//从会话中获取数据
System.out.println(session.getAttribute("sessionKey"));
//从请求中获取数据
//此方式无法获取请求中的数据,不知为何?
System.out.println(request.getAttribute("requestKey"));//返回null
//从请求中获取参数数据
//Struts2自动把参数注入到此Action中
System.out.println(getId());
System.out.println(getName().length);
//在应用中添加数据
application.setAttribute("newApplicationKey", "newApplicationValue");
//在会话中添加数据
session.setAttribute("newSessionKey", "newSessionValue");
//在请求中添加数据
request.setAttribute("newRequestKey", "newRequestValue");
//获取参数
System.out.println(request.getParameter("id"));
System.out.println(request.getParameter("name"));
return "success";
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String[] getName() {
return name;
}
public void setName(String[] name) {
this.name = name;
}
}
package org.rabbitx.web.struts2.action;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.util.ServletContextAware;
/**
* 使用实现ServletRequestAware,ServletContextAware的方式访问原生Web资源
*
* @author RabbitX
*
*/
public class TestServletAwareAction implements ServletRequestAware,ServletContextAware{
private String id;
private String[] name;
private ServletContext application;
private HttpSession session;
private HttpServletRequest request;
@Override
public void setServletContext(ServletContext application) {
this.application = application;
}
@Override
public void setServletRequest(HttpServletRequest request) {
this.request = request;
this.session = request.getSession();
}
public String execute()
{
//从请求中获取页面中添加到应用,会话和请求中的数据
//从应用中获取数据
System.out.println(application.getAttribute("applicationKey"));
//从会话中获取数据
System.out.println(session.getAttribute("sessionKey"));
//从请求中获取数据
//此方式无法获取请求中的数据,不知为何?
System.out.println(request.getAttribute("requestKey"));//返回null
//从请求中获取参数数据
//Struts2自动把参数注入到此Action中
System.out.println(getId());
System.out.println(getName().length);
//在应用中添加数据
application.setAttribute("newApplicationKey", "newApplicationValue");
//在会话中添加数据
session.setAttribute("newSessionKey", "newSessionValue");
//在请求中添加数据
request.setAttribute("newRequestKey", "newRequestValue");
//获取参数
System.out.println(request.getParameter("id"));
System.out.println(request.getParameter("name"));
return "success";
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String[] getName() {
return name;
}
public void setName(String[] name) {
this.name = name;
}
}
6. 配置Action
<?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> <package name="action" extends="struts-default"> <!-- 使用 ActionContext访问Web资源 --> <action name="actionContext" class="org.rabbitx.web.struts2.action.TestActionContextAction"> <result name="success">/pages/viewData.jsp</result> </action> <!-- 使用实现ApplicationAware, SessionAware,RequestAware, ParameterAware的方式访问Web资源 --> <action name="aware" class="org.rabbitx.web.struts2.action.TestAwareAction"> <result name="success">/pages/viewData.jsp</result> </action> <!-- 使用 ServletActionContext访问原生Web资源 --> <action name="servletActionContext" class="org.rabbitx.web.struts2.action.TestServletActionContextAction"> <result name="success">/pages/viewData.jsp</result> </action> <!-- 使用实现ServletRequestAware,ServletContextAware的方式访问原生Web资源 --> <action name="servletAware" class="org.rabbitx.web.struts2.action.TestServletAwareAction"> <result name="success">/pages/viewData.jsp</result> </action> </package> </struts>