Struts2:在Action中如何访问Web资源

Posted yy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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实现
  1. 使用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();

  1. 实现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对象,且可以调用其原生的方法。
  1. 使用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();
  1. 实现ServletXxxAware接口
 1 package com.dx.actions;
 2 
 3 import javax.servlet.ServletContext;
 4 以上是关于Struts2:在Action中如何访问Web资源的主要内容,如果未能解决你的问题,请参考以下文章

Struts2:在 Action 中访问 WEB 资源

Struts2 之 Action 类访问 WEB 资源

Struts2学习第三课 访问Web资源

struts2---访问WEB

Struts2之web元素访问与模板包含与默认Action使用

Java Web开发——Struts2 中.action和.do的奥秘