Struts2(四):在Action中如何访问Web资源
1、什么WEB资源?
HttpServletRequest,HttpServletRespone,HttpApplication,ServletContext,HttpSession等原生ServletAPI。
2、在Struts2中为什么要访问WEB资源?
B/S应用中的Controller必然会有场景需要访问WEB资源:向域对象中读写属性,读取Cookie,获取realPath等。
3、在Struts2中如何访问WEB资源?
a)和ServletAPI解耦的方式:只能有限的ServletAPI对象,只能访问有限的方法(读取请求参数,读写域对象的属性,使session失效),有些内容访问不到;
具体使用ActionContext;
实现XxxAware接口
b)和ServletAPI耦合的方式:可以访问更多的ServletAPI对象,且可以调用其原生的方法。
使用ServletServletContext;
实现ServletXxxAware接口。
- 怎么通过“和ServletAPI解耦的方式”实现访问有限的方法-使用ActionContext实现
- 使用ActionContext实现
首先,我们新建一个Struts002的工程,引入struts2的jar包,创建struts.xml,修改web.xml。
新建包com.dx.actions,在包下创建一个action类:TestActionContextFetchServletObjectAction.java
内容如下:
1 package com.dx.actions; 2 3 import java.util.Map; 4 5 import com.opensymphony.xwork2.ActionContext; 6 7 public class TestActionContextFetchServletObjectAction { 8 public String execute() { 9 // 0.通过ActionContext调用其getContext方法,获取到一个ActionContext实例对象。 10 // ActionContext是Action的上下文对象,可以从中获取当前Action需要的一起信息。 11 ActionContext context = ActionContext.getContext(); 12 13 // 1.获取ApplicationContext对应的Map,并向其中添加一个属性。 14 // 调用ActionContext对象的getApplication方法,获取application对象的Map对象。 15 Map<String, Object> applicationMap = context.getApplication(); 16 // 设置属性 17 applicationMap.put("applicationKey", "applicationValue"); 18 // 获取属性 19 Object appPageKey = applicationMap.get("applicationClientKey"); 20 System.out.println(appPageKey); 21 22 // 2.session 23 Map<String, Object> sessionMap = context.getSession(); 24 sessionMap.put("sessionKey", "sessionValue"); 25 26 Object sessionClientKey = sessionMap.get("sessionClientKey"); 27 System.out.println(sessionClientKey); 28 29 // 3.request 30 // ActionContext中並沒有提供getRequets方法來獲取request對應的Map. 31 // 需要手工调用ActionContext的get方法,并传入一个request字符串来获取request对象的Map对象。 32 Map<String, Object> requestMap = (Map<String, Object>) context.get("request"); 33 //设置属性 34 requestMap.put("requestKey", "requestValue"); 35 // 获取属性 36 Object requestClientKey = requestMap.get("requestClientKey"); 37 System.out.println(requestClientKey); 38 39 // 4.parameters 40 // 获取请求参数对应的Map,并获取指定的参数值。 41 // 键:请求参数的名字,值:请求参数的值对应的字符串数组。 42 // 注意: 1.getParameters返回的值为Map<String,Object>,而不是Map<String,String[]> 43 // 2.parameters这个Map是只读的,不能写入数据,如果写入,但不出错误,但也不起作用。 44 Map<String, Object> parametersMap = context.getParameters(); 45 // 读取属性 46 Object parametersClientKey = parametersMap.get("parametersClientKey"); 47 System.out.println(parametersClientKey); 48 // 设置值,并不起作用的。 49 parametersMap.put("parameterKey", "parametersValue"); 50 51 return "success"; 52 } 53 }
上边的action类,是一个缺省继承ActionSupport类.
在struts.xml中注册action,修改后的struts.xml内容:
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" 4 "http://struts.apache.org/dtds/struts-2.3.dtd"> 5 6 <struts> 7 <constant name="struts.action.extension" value="action" /> 8 <constant name="struts.enable.DynamicMethodInvocation" value="false" /> 9 <constant name="struts.devMode" value="false" /> 10 11 <package name="default" namespace="/" extends="struts-default"> 12 <action name="testServletObject" class="com.dx.actions.TestActionContextFetchServletObjectAction"> 13 <result>/WEB-INF/test-context.jsp</result> 14 </action> 15 </package> 16 </struts>
在WebContent文件夹下新建一个index.jsp:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 </head> 9 <body> 10 <a href="testServletObject.action?parameterClientKey=hello">Test 11 Fetch Servlet Object From ActionContext object.</a>
<% application.setAttribute("applicationClientKey", "applicationClientValue"); %>
<% session.setAttribute("sessionClientKey", "sessionClientValue"); %>
<% request.setAttribute("requestClientKey", "requestClientValue"); %>
12 </body> 13 </html>
在该页面中包含了一个连接,该连接内容指定了需要跳转的页面。同时,还给页面中Servlet域对象application,session,request属性赋值了值。
/WEB-INF/test-context.jsp页面内容:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 </head> 9 <body> 10 <h4>Test fetch Servlet object from ActionContext object</h4> 11 applicationKey:${applicationScope.applicationKey} 12 <br> 13 sessionKey:${sessionScope.sessionKey} 14 <br> 15 requestKey:${requestScope.requestKey} 16 <br> 17 parameterKey:${parameters.parameterKey} 18 <br> 19 </body> 20 </html>
用来显示action的转发内容,同时显示通过ActionContext对象中获取到的application,session,request,parameters对象的赋值结果展示。
页面运行结果:
通过以上例子,我们了解到了如何通过“和ServletAPI解耦的方式”来获取Servlet域对象的方法。
0.ActionContext是Action的上下文对象,可以从中获取当前Action需要的一起信息,通过ActionContext调用其getContext方法,获取到一个ActionContext实例对象。
1.获取ApplicationContext对应的Map,并向其中添加一个属性。
调用ActionContext对象的getApplication方法,获取application对象的Map对象。
Map<String, Object> applicationMap = context.getApplication();
2.session
Map<String, Object> sessionMap = context.getSession();3.request
ActionContext中並沒有提供getRequets方法來獲取request對應的Map.
需要手工调用ActionContext的get方法,并传入一个request字符串来获取request对象的Map对象。
Map<String, Object> requestMap = (Map<String, Object>) context.get("request");4.parameters
获取请求参数对应的Map,并获取指定的参数值。
键:请求参数的名字,值:请求参数的值对应的字符串数组。
注意: 1.getParameters返回的值为Map<String,Object>,而不是Map<String,String[]>
2.parameters这个Map是只读的,不能写入数据,如果写入,但不出错误,但也不起作用。
Map<String, Object> parametersMap = context.getParameters();
- 实现XxxAware接口
struts.xml
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" 4 "http://struts.apache.org/dtds/struts-2.3.dtd"> 5 6 <struts> 7 <!-- action路径的扩展名:*.action,*.do,无扩展名 --> 8 <constant name="struts.action.extension" value="action,do," /> 9 <constant name="struts.enable.DynamicMethodInvocation" value="false" /> 10 <constant name="struts.devMode" value="false" /> 11 12 <package name="default" namespace="/" extends="struts-default"> 13 <action name="testServletObject" 14 class="com.dx.actions.TestActionContextFetchServletObjectAction"> 15 <result>/WEB-INF/test-context.jsp</result> 16 </action> 17 <action name="gotoLoginPage" class="com.opensymphony.xwork2.ActionSupport" method="execute"> 18 <result name="success">/login.jsp</result> 19 </action> 20 <action name="login" class="com.dx.actions.TestWithXXXAware" 21 method="login"> 22 <result name="login-success">/WEB-INF/login-success.jsp</result> 23 </action> 24 <action name="logout" class="com.dx.actions.TestWithXXXAware" 25 method="logout"> 26 <result name="logout-success">/login.jsp</result> 27 </action> 28 </package> 29 30 </struts>
TestWithXXXAware.java:
1 package com.dx.actions; 2 3 import java.util.Map; 4 5 import org.apache.struts2.ServletActionContext; 6 import org.apache.struts2.dispatcher.SessionMap; 7 import org.apache.struts2.interceptor.ApplicationAware; 8 import org.apache.struts2.interceptor.ParameterAware; 9 import org.apache.struts2.interceptor.RequestAware; 10 import org.apache.struts2.interceptor.SessionAware; 11 12 13 /** 14 * XxxAware一般情況下,一個Action類中包含了多個Action方法,同時這個多個Action中都需要使用域對象或parameters. 15 * ActionContext的方式,一般情況下一個Action類中包含了一個Action方法, 16 * 或者需要使用SessionMap清楚session的時候會使用。 17 */ 18 public class TestWithXXXAware implements ApplicationAware, RequestAware, SessionAware, ParameterAware { 19 private String username; 20 21 public void setUsername(String username) { 22 this.username = username; 23 } 24 25 /** 26 * login action 27 * */ 28 public String login() { 29 // 记录登录成功的用户信息。 30 // 从request中获取不到form提交的参数信息,为什么呢? 31 String usernameWithActionContext = (String) request.get("username"); 32 String usernameWithServletActionContext=ServletActionContext.getRequest().getParameter("username"); 33 34 session.put("loginusername", username); 35 36 System.out.println("with setter:"+username); 37 System.out.println("with ActionContext.get(\"request\").get(\"username\"):"+usernameWithActionContext); 38 System.out.println("with ServletActionContext.getRequest().getParameter(\"username\"):"+usernameWithServletActionContext); 39 40 // 实现成功登录计数 41 Integer count = (Integer) application.get("count"); 42 43 if (count == null || count < 0) { 44 count = 0; 45 } 46 47 count++; 48 49 application.put("count", count); 50 51 return "login-success"; 52 } 53 54 /** 55 * logout action 56 * */ 57 public String logout() { 58 // 实现成功登录计数 59 Integer count = (Integer) application.get("count"); 60 61 if (count == null || count < 0) { 62 count = 0; 63 } else { 64 count--; 65 } 66 application.put("count", count); 67 68 // 使得session失效 69 ((SessionMap) session).invalidate(); 70 71 return "logout-success"; 72 } 73 74 private Map<String, String[]> parameters; 75 private Map<String, Object> session; 76 private Map<String, Object> request; 77 private Map<String, Object> application; 78 79 @Override 80 public void setParameters(Map<String, String[]> parameters) { 81 this.parameters = parameters; 82 } 83 84 @Override 85 public void setSession(Map<String, Object> session) { 86 this.session = session; 87 } 88 89 @Override 90 public void setRequest(Map<String, Object> request) { 91 this.request = request; 92 } 93 94 @Override 95 public void setApplication(Map<String, Object> application) { 96 this.application = application; 97 } 98 99 }
login.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 </head> 9 <body> 10 <form action="login" method="post"> 11 User Name: 12 <input type="text" name="username" /> 13 <br /> 14 <input name="submit" type="submit" value="submit"/> 15 </form> 16 </body> 17 </html>
login-success.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 </head> 9 <body> 10 欢迎${sessionScope.loginusername}登录! 11 <br/> 12 当前登录人数:${applicationScope.count} 13 <br/> 14 <a href="logout.do">logout</a> 15 <br/> 16 </body> 17 </html>
后台打印信息:
with setter:ddddddddddd
with ActionContext.get("request").get("username"):null
with ServletActionContext.getRequest().getParameter("username"):ddddddddddd
页面登录信息:
- 和ServletAPI耦合的方式:可以访问更多的ServletAPI对象,且可以调用其原生的方法。
- 使用ServletServletContext实现
String usernameWithServletActionContext=ServletActionContext.getRequest().getParameter("username");
1 HttpServletResponse httpServletResponse=ServletActionContext.getResponse(); 2 HttpServletRequest httpServletRequest=ServletActionContext.getRequest(); 3 HttpSession httpSession=ServletActionContext.getRequest().getSession(); 4 ActionContext actionContext=ServletActionContext.getContext();
- 实现ServletXxxAware接口
1 package com.dx.actions; 2 3 import javax.servlet.ServletContext; 4 import javax.servlet.http.HttpServletRequest; 5 import javax.servlet.http.HttpServletResponse; 6 7 import org.apache.struts2.interceptor.ServletRequestAware; 8 import org.apache.struts2.interceptor.ServletResponseAware; 9 import org.apache.struts2.util.ServletContextAware; 10 11 public class TestServletXxxAware implements ServletContextAware, ServletRequestAware,ServletResponseAware { 12 13 @Override 14 public void setServletResponse(HttpServletResponse arg0) { 15 // TODO Auto-generated method stub 16 17 } 18 19 @Override 20 public void setServletRequest(HttpServletRequest arg0) { 21 // TODO Auto-generated method stub 22 23 } 24 25 @Override 26 public void setServletContext(ServletContext arg0) { 27 // TODO Auto-generated method stub 28 29 } 30 31 }
基础才是编程人员应该深入研究的问题,比如:
1)List/Set/Map内部组成原理|区别
2)mysql索引存储结构&如何调优/b-tree特点、计算复杂度及影响复杂度的因素。。。
3)JVM运行组成与原理及调优
4)Java类加载器运行原理
5)Java中GC过程原理|使用的回收算法原理
6)Redis中hash一致性实现及与hash其他区别
7)Java多线程、线程池开发、管理Lock与Synchroined区别
8)Spring IOC/AOP 原理;加载过程的。。。
【+加关注】。