zoukankan      html  css  js  c++  java
  • [原创]java WEB学习笔记55:Struts2学习之路---详解struts2 中 Action,如何访问web 资源,解耦方式(使用 ActionContext,实现 XxxAware 接口),耦合方式(通过ServletActionContext,通过实现 ServletRequestAware, ServletContextAware 等接口的方式)

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用

    内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系。

    本人互联网技术爱好者,互联网技术发烧友

    微博:伊直都在0221

    QQ:951226918

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    1.Action 类

      1)action: 应用程序可以完成的每一个操作. 代表一个sturts2 的请求。例如: 显示一个登陆表单; 把产品信息保存起来

      2)Action类: 普通的 Java 类,能够处理struts2 请求的java类, 可以有属性和方法, 同时必须遵守下面这些规则:

        ① 属性的名字必须遵守与 JavaBeans 属性名相同的命名规则. 属性的类型可以是任意类型. 从字符串到非字符串(基本数据库类型)之间的数据转换可以自动发生

        ② 必须有一个不带参的构造器:反射

        ③ 至少有一个供 struts 在执行这个 action 时调用的方法

          ④ 同一个 Action 类可以包含多个 action 方法.

        ⑤ Struts2 会为每一个 HTTP 请求创建一个新的 Action 实例。即,Action 不是单例的,是线程安全的。

     

    2.在Action中如何访问web资源

    1)什么是web 资源

      HttpServletRequest, HttpSession,ServletContext 等原生的Servlet API

    2)为什么访问web 资源?

      B/S 应用的controller 中必然需要访问web资源:向域对象中读写属性,读写 cookie,获取realPath  ....

    3) 如何访问?

      ① 和servlet API 解耦的方式:只能访问有限的Servelt API 对象,且只能访问其有限的方法(读取请求参数,读写域对象的属性,是session 失效 ... )

        > 使用 ActionContext

        >实现 XxxAware 接口

    注:为了避免与 Servlet API 耦合在一起, 方便 Action 做单元测试, Struts2 对 HttpServletRequest, HttpSession 和 ServletContext 进行了封装, 构造了 3 个 Map 对象来替代这 3 个对象,

      在 Action 中可以直接使用 HttpServletRequest, HttpServletSession, ServletContext 对应的 Map 对象来保存和读取数据.

      

      ② 和servlet API 耦合的方式:可以访问更多的Servlet API对象,且可以调用其原生的方法。

        > 使用 ServletContext

        >  实现ServletXxxAware接口

     

    3.1 和servlet API 解耦的方式

      1)通过 ActionContext 访问 Web 资源:ActionContext 是 Action 执行的上下文对象, 在 ActionContext 中保存了 Action 执行所需要的所有对象, 包括 parameters, request, session, application 等.

        > 获取 HttpSession 对应的 Map 对象: public Map getSession() , session 对应的Map 实际上是SessionMap 类型的,强转之后调用其invalidate() 方法,可以使其session 失效

        > 获取 ServletContext 对应的 Map 对象: public Map getApplication()

        > 获取请求参数对应的 Map 对象: public Map getParameters()

        > 获取 HttpServletRequest 对应的 Map 对象: public Object get(Object key):ActionContext 类中没有提供类似 getRequest() 这样的方法来获取 HttpServletRequest 对应的 Map 对象. 要得到 HttpServletRequest 对应的 Map 对象, 可以通过为 get() 方法传递 “request” 参数实现

       struts.xml  

     1 <package name="testAction" namespace="/" extends="struts-default">
     2     
     3         <action name="TestActionContext" class="com.jason.struts.action.TestActionContextAction" method="execute">
     4         
     5         <result>/test-actionContext.jsp</result>
     6         
     7         </action>
     8     
     9     </package>
    10     

        

    TestActionContextAction.java
     1 package com.jason.struts.action;
     2 
     3 import java.util.Map;
     4 
     5 import com.opensymphony.xwork2.ActionContext;
     6 
     7 /**
     8  * 
     9  * @ClassName:TestActionContextAction
    10  * @Description:TODO
    11  * @author: jason_zhangz@163.com
    12  * @date:2016年8月2日下午6:01:48
    13  * 
    14  *
    15  */
    16 public class TestActionContextAction {
    17     
    18     public String execute(){
    19         
    20         //0.获取actionContext对象,是Action 的上下文对象。可以从中获取到Action获取所以信息
    21         
    22         ActionContext actionContext = ActionContext.getContext();
    23         
    24         //1.获取application 对应的Map,并向其中添加一个属性
    25             //通过application 对象的 getApplication() 方法来获取application 对象的map 对象
    26             Map<String, Object> applicationMap = actionContext.getApplication();
    27             //设置属性
    28             applicationMap.put("applicationKey", "applicationValue");
    29             
    30         //2.session
    31             Map<String, Object> sessionMap = actionContext.getSession();
    32             sessionMap.put("sessionKey", "sessionValue");
    33             
    34         
    35         //3.request
    36         //ActionContext 中并没有提供 getRequest 方法来获取 request 对应的 Map,需要手工调用get(),传入 requet 字符串来获取    
    37             
    38             Map<String, Object> requsetMap = (Map<String, Object>) actionContext.get("request");
    39             requsetMap.put("requestKey", "requestValue");
    40         
    41         //4.获取请求参数对应的Map,并且获取指定的参数值
    42         //键:请求参数的名字;值:请求参数的值对应的字符串数组
    43         //注意:1. getParameters 的返回值为Map<String, Object> ,而不是Map<String ,String[]>
    44         //       2.parameters 这个Map 只能读,不能写入数据,如果写入,但不出错,同时也不起作用
    45             Map<String, Object> paramters = actionContext.getParameters();  
    46             System.out.println(((String [])paramters.get("name"))[0]);
    47             
    48             
    49             paramters.put("age", 100);
    50         return "success";
    51     }
    52 
    53 }

    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>testAction index page</title>
     8 </head>
     9 <body>
    10 
    11     <a href="TestActionContext.action?name=jason"> Test ActionContext</a>
    12 </body>
    13 </html>

    test-actionContest.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>test-actionContext  page</title>
     8 </head>
     9 <body>
    10 
    11     <h4>test-actionContext page</h4>
    12     
    13     application: ${applicationScope.applicationKey }
    14     <br><br>
    15     
    16     
    17     application: ${sessionScope.sessionnKey }
    18     <br><br>
    19     
    20     
    21     request:${requestScope.requestKey }
    22     <br><br>
    23     
    24     age:${parameters.age }
    25     
    26     
    27 </body>
    28 </html>

    3.2实现 XxxAware 接口

     TestAwareAction.java

     1 package com.jason.struts.action;
     2 
     3 import java.util.Map;
     4 
     5 import org.apache.struts2.interceptor.ApplicationAware;
     6 import org.apache.struts2.interceptor.ParameterAware;
     7 import org.apache.struts2.interceptor.RequestAware;
     8 import org.apache.struts2.interceptor.SessionAware;
     9 
    10 /**
    11  * 
    12  * @ClassName:TestAwareAction
    13  * @Description:测试 解耦 实现 XxxAware 接口
    14  * @author: jason_zhangz@163.com
    15  * @date:2016年8月5日下午5:28:42
    16  * 
    17  *
    18  */
    19 public class TestAwareAction  implements ApplicationAware ,SessionAware,RequestAware,ParameterAware{
    20     //通过实现不同的Aware 的接口,之后实现 setXX 方法,而struts2 用注入的方式,将对应的map 对象注入到自己所定义个私有变量中,之后调用execute方法
    21     
    22     public String execute(){
    23         
    24         //1.向application 中加入一个属性:applicationKey - applicationValue
    25         application.put("applicationKey2", "applicationValue2");
    26         //2.从application 中读取一个属性data,打印
    27         System.out.println(application.get("date"));
    28         
    29         return "success";
    30     }
    31 
    32     private Map<String, Object> application;
    33     private Map<String,String[]> parameters;
    34     private Map<String, Object> request;
    35     private Map<String, Object> session;
    36     
    37     @Override
    38     public void setApplication(Map<String, Object> application) {
    39         
    40         this.application = application;
    41     }
    42     @Override
    43     public void setParameters(Map<String, String[]> parameters) {
    44         this.parameters = parameters;
    45         
    46     }
    47     @Override
    48     public void setRequest(Map<String, Object> request) {
    49         this.request = request;
    50         
    51     }
    52     @Override
    53     public void setSession(Map<String, Object> session) {
    54         this.session = session;
    55         
    56     }
    57     
    58     
    59 }

     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     <!-- 
     8         package: 包. Struts2 使用package 来组织模块
     9         name属性:必须. 用于其他的包引用当前包。一般为当前模块的名字
    10         extends:当前包继承哪个包,继承的,即可以继承其中的所有的配置。通常情况下,继承 struts-default
    11         namespace:可选,如果没有给出,则 以 "/" 为默认值。若namespace有一个非默认值,则要想调用这个包里面的action,则必须把这个属性所定义的命名空间添加到先关的URI 字符串里。在servletPath 前面添加。
    12          例如: http://localhost:8080/contextpath/namespace/servletPath
    13          
    14          
    15      -->
    16     <!-- <package name="helloword" extends="struts-default">
    17         
    18         配置一个action: 一个struts2 的请求就是一个action
    19         
    20             name:对应一个Struts2 的请求的名字(或者对应一个servletPath,但是去除 / 和 扩展名),不含扩展名
    21             class:的默认值为:com.opensymphony.xwork2.ActionSupport
    22             method:的默认值为:execute
    23             
    24         
    25         <action name="product-input" 
    26                 class="com.opensymphony.xwork2.ActionSupport"
    27                 method="execute">
    28         
    29                 
    30             result:结果。即,要访问的路径。表示action 方法执行后可能返回的一个结果。一个action节点可能有多个result 子节点。多个子节点使用name属性来区分,
    31             name:标示一个一个result,和action 方法的返回值对应。默认值为 success
    32             type:表示结果的类型,默认为dispatcher(转发到 结果)
    33         
    34             <result name="success" type="dispatcher">/struts2/input.jsp</result>
    35         </action>
    36         
    37         
    38         <action name="product-save" class="com.jason.struts.helloword.Product" method="save">
    39             <result name="details">/struts2/details.jsp</result>
    40 
    41         </action>
    42     
    43     
    44     
    45     </package> 
    46     
    47      -->
    48     
    49      <package name="testAction" namespace="/" extends="struts-default">
    50     
    51          <action name="TestActionContext" class="com.jason.struts.action.TestActionContextAction" method="execute">
    52         
    53                 <result>/test-actionContext.jsp</result>
    54         
    55         </action>
    56         
    57         
    58         <action name="TestAware" class="com.jason.struts.action.TestAwareAction" method="execute">
    59         
    60                 <result>/test-aware.jsp</result>
    61         
    62         </action>
    63     
    64     </package>
    65     
    66     
    67     
    68     
    69 
    70     
    71     
    72 </struts>

     test-aware.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>Test Aware Page<</title>
     8 </head>
     9 <body>
    10 
    11     <h4>Test Aware Page</h4>
    12     
    13      application:${applicationScope.applicationKey2 }
    14 </body>
    15 </html>

    index.jsp

     1 <%@page import="java.util.Date"%>
     2 <%@ page language="java" contentType="text/html; charset=UTF-8"
     3     pageEncoding="UTF-8"%>
     4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
     5 <html>
     6 <head>
     7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     8 <title>testAction index page</title>
     9 </head>
    10 <body>
    11     <%
    12         Date date = new Date();
    13         application.setAttribute("date", date);
    14     %>
    15     <a href="TestActionContext.action"> Test ActionContext</a>
    16     <br>
    17     <br>
    18     <a href="TestAware.action">  TestAware</a>
    19 </body>
    20 </html>

    3.3.两种解耦方式web资源的比较

      1)若一个Action 类中有对个 Action 方法,且多个方法,使用域对象的 Map 或 parameters ,则建议使用实现了Aware 接口的方式。

    3.4. 与Servlet 耦合的访问方式:需要用到原生的API

    方式一:

      1) 直接访问 Servlet API 将使 Action 与 Servlet 环境耦合在一起,  测试时需要有 Servlet 容器, 不便于对 Action 的单元测试;

      2) 直接获取 HttpServletRequest 对象: ServletActionContext.getRequest();

        3) 直接获取 HttpSession 对象:ServletActionContext.getRequest().getSession();

       4) 直接获取 ServletContext 对象:ServletActionContext.getServletContext();

    TestServletActionContextAction.java
     1 package com.jason.struts.action;
     2 
     3 import javax.servlet.ServletContext;
     4 import javax.servlet.http.HttpServletRequest;
     5 import javax.servlet.http.HttpSession;
     6 
     7 import org.apache.struts2.ServletActionContext;
     8 
     9 public class TestServletActionContextAction {
    10 
    11     
    12         public String execute(){
    13             /**
    14              * ServletActionContext:可以获取到当前Action 对象需要的一切的servlet API 相关对象
    15              * 常用方法:
    16              *     1.获取 HttpServletRequest :ServletActionContext.getRequest()
    17              *  2.获取 HttpSession :ServletActionContext.getRequest().getSession()
    18              *  3.获取ServletContext:ServletActionContext.getServletContext()
    19              */
    20             
    21             HttpServletRequest request = ServletActionContext.getRequest();
    22             HttpSession session =  ServletActionContext.getRequest().getSession();
    23             ServletContext servletContext  = ServletActionContext.getServletContext();
    24             
    25             System.out.println("execute ...");
    26             
    27             
    28             return "success";
    29         }
    30 }

    struts.xml

    1     
    2         <action name="TestServletActionContext" class="com.jason.struts.action.TestServletActionContextAction">
    3             <result>/success.jsp</result>
    4         </action>

    index.jsp

    1 <a href="TestServletActionContext.action">  TestServletActionContext</a>

    方式二:

    通过实现 ServletRequestAware, ServletContextAware 等接口的方式

    TestSerlvetAwareAction.java
     1 package com.jason.struts.action;
     2 
     3 import javax.servlet.ServletContext;
     4 import javax.servlet.http.HttpServlet;
     5 import javax.servlet.http.HttpServletRequest;
     6 import javax.servlet.http.HttpServletResponse;
     7 
     8 import org.apache.struts2.interceptor.ServletRequestAware;
     9 import org.apache.struts2.interceptor.ServletResponseAware;
    10 import org.apache.struts2.util.ServletContextAware;
    11 
    12 
    13 /**
    14  * 
    15  * @ClassName:TestSerlvetAwareAction
    16  * @Description:通过实现ServletXxxAware 接口的方式可以有Struts2 注入需要的Servlet 相关对象
    17  * 
    18  *     ServletRequestAware: 注入HttpServletRequest 对象(常用)
    19  *     ServletContextAware: 注入 ServletContext 对象(常用)
    20  *     ServletResponseAware:
    21  * 
    22  * @author: jason_zhangz@163.com
    23  * @date:2016年8月18日下午4:35:21
    24  * 
    25  *
    26  */
    27 public class TestSerlvetAwareAction  implements ServletRequestAware, ServletContextAware,ServletResponseAware{
    28 
    29     
    30     public String  execute(){
    31     
    32             System.out.println("execute ...");
    33             
    34             return "success";
    35     }
    36     
    37     private ServletContext servletContext;
    38     @Override
    39     public void setServletContext(ServletContext context) {
    40         System.out.println(context);
    41         //org.apache.catalina.core.ApplicationContextFacade@47da4d19
    42         this.servletContext = context;
    43         
    44     }
    45     
    46     private HttpServletRequest request;
    47     @Override
    48     public void setServletRequest(HttpServletRequest request) {
    49         System.out.println(request);
    50         //org.apache.struts2.dispatcher.StrutsRequestWrapper@b8519f4
    51         this.request = request;
    52         
    53     }
    54 
    55     private HttpServletResponse response;
    56     @Override
    57     public void setServletResponse(HttpServletResponse response) {
    58         System.out.println(response);
    59         //org.apache.catalina.connector.ResponseFacade@4f6ae814
    60         this.response = response;
    61     }
    62 
    63 }

    Struts.xml

    1 <action name="TestServletAwareAction" class="com.jason.struts.action.TestSerlvetAwareAction">
    2         
    3             <result>/success.jsp</result>
    4         </action>

     

     index.jsp

    1 <a href="TestServletAwareAction.action">  TestServletAwareAction</a>

      

     

  • 相关阅读:
    XML基础(二)
    XML基础(一)
    转载:数据库应用开发工具Toad使用笔记
    Oracle数据库获取一行记录中某几个字段的最大值/最小值函数
    设置Android让EditText不自动获取焦点
    android TextView selector点击样式改变
    Jenkins build java app under redhat
    Yum
    git windows
    jenkins redhat installation using war file .
  • 原文地址:https://www.cnblogs.com/jasonHome/p/5729671.html
Copyright © 2011-2022 走看看