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>