zoukankan      html  css  js  c++  java
  • Java实战之01Struts205contextMAP、EL、OGNL

    十五、contextMap

    1、动作类的生命周期

    明确:动作类是多例的,每次动作访问,动作类都会实例化。所以是线程安全的。与Struts1的区别是,struts1的动作类是单例的。

    2、请求动作的数据存放

     问题:

    每次请求时,都会产生一些请求数据,这些数据存放到哪里去了?

     明确:

    在每次动作执行前,核心控制器StrutsPrepareAndExecuteFilter都会创建一个ActionContextValueStack对象。且每次动作访问都会创建。

    这两个对象存储了整个动作访问期间用到的数据。并且把数据绑定到了线程局部变量(ThreadLocal)上了。所以是线程安全的。

    3contextMap:存储数据

    Struts2的官方文档对contextMap的说明:

    contextMap中存放的主要内容

    Key

    Value

    说明

    value stack (root)

    java.util.List

    没有root这个keycontextMap中它有key,但是我们不用。它是一个list(com.opensymphony.xwork2.util.ValueStack.ValueStack是它的key)

    application

    java.util.Map<String,Object>

    ServletContext中的所有属性。

    session

    java.util.Map<String,Object>

    HttpSession中的所有属性。

    request

    java.util.Map<String,Object>

    ServletRequest中的所有属性。

    parameters

    java.util.Map

    参数

    attr

    java.util.Map

    把页面、请求、会话、应用范围内的所有属性放到一起。

    注意:

    除了value stack之外,全是map,而contextMap也是一个map。其实就是Map中又封装的Map。(很像dbutilsKeyedHandler封装数据的结构,只是封装数据的结构)

    查看contextMap中的数据:

    在页面上使用<s:debug/>

    十六、contextMap中的数据操作

    1、存数据:

    需要熟悉ActionContextvalueStackAPI。框架为我们存数据。

    1.1、利用ActionContext存数据

     1 public String demo1(){
     2         //1.获取到ActionContext对象
     3         ActionContext context = ActionContext.getContext();//从当前线程上获取
     4         //2.往大map中存入数据
     5         context.put("contextMap", "hello context map");
     6         
     7         //3.往指定的小Map中存入数据(request,session,application)
     8         //Map<String,Object> sessionMap = (Map<String, Object>) context.get("session");
     9         //第一种方式:使用map操作
    10         Map<String,Object> sessionMap = context.getSession();
    11         sessionMap.put("sessionMap", "hello session map");
    12         //第二种方式:使用原始ServletAPI存入数据
    13         HttpSession session = ServletActionContext.getRequest().getSession();
    14         session.setAttribute("sessionAttr","hello session attribute");
    15         
    16         //4.往application的map中存入数据
    17         //第一种方式:使用map操作
    18         Map<String,Object> applicationMap = context.getApplication();
    19         applicationMap.put("applicationMap", "hello application map");
    20         //第二种方式:使用原始ServletAPI对象
    21         ServletContext application = ServletActionContext.getServletContext();
    22         application.setAttribute("applicationAttr", "hello application attribute");
    23         return SUCCESS;
    24     }

    1.2、利用ValueStack存数据

    a、如何获取ValueStack

     1 /**
     2  * 利用ValueStack存取数据操作
     3  * 明确:
     4  *     1、它本身是一个List结构,同时具备了栈的特点。
     5  *     2、它里面只能存放对象,没有key,value的概念。
     6  * @author zhy
     7  *
     8  */
     9 public class Demo2Action extends ActionSupport {
    10     
    11     private String name = "泰斯特";
    12 
    13     public String demo2(){
    14         //1.获取valueStack
    15         //先获取ActionContext
    16         ActionContext context = ActionContext.getContext();
    17         context.put("contextMap", "hello context map");
    18         //再使用ActionContext中的getValueStack方法获取
    19         ValueStack vs = context.getValueStack();
    20         /*
    21          * 压栈操作
    22          */
    23         Student s1 = new Student("test",18,"male");
    24         vs.push(s1);
    25         
    26         Student s2 = new Student("test1",20,"female");
    27         vs.push(s2);
    28         
    29         return SUCCESS;
    30     }
    31 
    32     public String getName() {
    33         return name;
    34     }
    35 
    36     public void setName(String name) {
    37         this.name = name;
    38     }
    39 
    40 }

    bValueStack中的getRoot()方法:

    c、CompoundRoot是什么:

    d、栈操作:

    2、取数据:用Struts2的标签(OGNL表达式)JSP

    使用OGNL表达式来去,struts2OGNL表达式必须写在struts2标签中。

    2.1、使用s:property取数据

    a、取contextMap中的数据,需使用#

     1 <body>
     2       <%--1.获取ValueStack中的数据 :
     3           当我们使用s:property不指定value属性时,默认获取的是栈顶元素(对象)
     4           注意:获取的是一个对象。
     5           只有不使用value属性时,才获取的是对象。
     6           剩余的情况全是:
     7               根据属性名称获取属性值!!!!!!!!
     8       --%>
     9       <s:property/>
    10       <hr/>
    11       <%--2.获取指定属性的值 
    12           当s:property标签的value属性没有使用#号时,是从ValueStack中获取数据
    13           把value的取值当做property name,从栈顶逐个元素往下寻找,找和value取值一样的属性,
    14           找到了,把值获取回来。只要找到了,就不再继续寻找。
    15           
    16           
    17           获取valueStack中的数据,不用写#号。并且直接写属性名称即可。
    18       --%>
    19       <s:property value="name"/>
    20       <hr/>
    21       <%--3.获取指定位置指定属性的值 
    22           [1]表示的不是属性名称出现的索引位置。
    23           而是指的集合中元素(对象)的索引位置。
    24           
    25           当我们使用[n].propertyname方式获取值时,它就是把栈中下标为n的元素看成是栈顶元素,逐个往下寻找。
    26       --%>
    27       <s:property value="[1].name"/>
    28       <hr/>
    29       <%--4.ValueStack中的findValue方法 --%>
    30       <% ActionContext ac = ActionContext.getContext(); 
    31          ValueStack vs = ac.getValueStack();
    32          Object obj = vs.findValue("name");
    33          Object obj1 = vs.findValue("[2].name");
    34          out.print(obj);
    35          out.print("<hr/>");
    36          out.print(obj1);
    37          out.print("<hr/>");
    38          Object obj2 = vs.findValue("#contextMap");
    39          out.print("aaaa:"+obj2);
    40       %>
    41       <%-- <s:property value="#contextMap"/> --%>
    42     <s:debug/> 
    43   </body>

    b、取contextMap里面ValueStack中对象的属性:直接写属性名

    1               <tr>
    2                   <td><s:property value="name"/></td>
    3                   <td><s:property value="age"/></td>
    4                   <td><s:property value="gender"/></td>
    5               </tr>

    OGNL的使用总结:

    1.中对象的属性不使用#

    2.contextMapkey的值,要使用#

    2.2ValueStackfindValue方法(我们在Jsp上调用的都是findValue

    十七、Struts2EL的改变

    1Struts2中使用EL的问题:

    前提:

    我们应该知道,如果我们没有往值栈()中放入数据的话,那么我们的动作类默认是在值栈的栈顶。

    问题:

    我们放到请求域中的属性,使用EL表达式取出来了。但是放到应用域中的属性,使用EL表达式没取出来。

    2、关于EL问题的分析:

    分析:

    我们知道EL表达式是从四大域对象中依次查找属性。搜索范围是由小到大。page Scope————>request Scope————>sessionScope————>application Scope

    但是通过测试发现,搜索完request范围后就没有继续搜索,而是返回了ValueStack中栈顶对象name属性的值。

    3Struts2EL查找顺序改变总结:

    EL表达式: page Scope————>request Scope————>sessionScope————>application Scope

    OGNL表达式:page Scope————>request Scope————>valueStack(根中)————>contextMap————>sessionScope————>application Scope

    4OGNL的特殊说明:

     1 public String demo3(){
     2         //1.获取HttpServletRequest的对象
     3         HttpServletRequest  request = ServletActionContext.getRequest();
     4         //2.往请求域中存放一个name
     5         //request.setAttribute("name", "请求域中的name");
     6         //3.获取HttpSession
     7         HttpSession session = request.getSession();
     8         session.setAttribute("name", "会话域中的name");
     9         
    10         ActionContext context = ActionContext.getContext();
    11         context.put("name", "大Map中的name");
    12         
    13         return SUCCESS;
    14     }

    十八、OGNL配合通用标签的其他使用

    1iterator标签

     1 /**
     2  * iterator标签的使用
     3  * @author zhy
     4  *
     5  */
     6 public class Demo4Action extends ActionSupport {
     7     
     8     private List<Student> students;
     9     
    10     public String demo4(){
    11         //1.获取HttpServletRequest的对象
    12         //HttpServletRequest  request = ServletActionContext.getRequest();
    13         //就相当于从数据库中获取学生列表
    14         students = new ArrayList<Student>();
    15         students.add(new Student("test1",18,"male"));
    16         students.add(new Student("test2",21,"female"));
    17         students.add(new Student("test3",22,"male"));
    18         //2.把查询出来的学生列表存入请求域中
    19         //request.setAttribute("students", students);
    20         
    21         return SUCCESS;
    22     }
    23 
    24     public List<Student> getStudents() {
    25         return students;
    26     }
    27 
    28     public void setStudents(List<Student> students) {
    29         this.students = students;
    30     }
    31 }
    1         <s:iterator value="students">
    2             <tr>
    3                   <td><s:property value="name"/></td>
    4                   <td><s:property value="age"/></td>
    5                   <td><s:property value="gender"/></td>
    6               </tr>
    7         </s:iterator>

    2Struts2#,$,%符号的使用

    2.1#

    a、取ActionContextkey时使用,例如<s:property value="#name" />

    bOGNL中创建Map对象时使用,例如:<s:radio list="#{'male':'','female':''}" />

    2.2$

    a、在JSP中使用EL表达式时使用,例如${name}

    b、在xml配置文件中,编写OGNL表达式时使用,例如文件下载时,文件名编码。struts.xml——>${@java.net.URLEncoder.encode(filename,"UTF-8")}

    2.3%

    struts2中,有些标签的value属性取值就是一个OGNL表达式,例如<s:property value="OGNL Expression" />

    还有一部分标签,value属性的取值就是普通字符串,例如<s:textfield value="username"/>,如果想把一个普通的字符串强制看成时OGNL,就需要使用%{}把字符串套起来。

    例如<s:textfield value="%{username}"/>。当然在<s:property value="%{OGNL Expression}" />也可以使用,但不会这么用。

    3、其他标签

    3.1if标签,elseif标签 else标签

     1 <%--1、s:if s:elseif s:else 
     2         作用:
     3             进行条件判断。
     4         属性:
     5             test里面的内容是一个逻辑运算,返回的结果应该是一个布尔类型值。
     6             可以使用常量运算,还可以是OGNL表达式的逻辑 运算
     7             
     8             test的取值可以是OGNL表达式,但是只能在ValueStack中取值
     9             
    10     --%>
    11     <%--没有经过动作类
    12      ActionContext ac = ActionContext.getContext();
    13         ac.put("name", "test");
    14      --%>
    15     <s:if test="name == null">
    16         用户名没有了
    17     </s:if>
    18     <s:elseif test="#name == 'test'">
    19         是一个测试用户
    20     </s:elseif>    

    3.2urla标签

     1 <%--2、s:url 和 s:a
     2          s:url标签:
     3              作用:是把指定路径存入contextMap中
     4              属性:
     5                  action:直接写动作名称。不用再写${pageContext.request.contextPath}
     6                  namespace:指定动作所在的名称空间,如果该动作是在默认名称空间下可以不写
     7                  var:取值是一个普通字符串。把var的取值当做key,把action的取值当做value,存入contextMap中
     8          s:param标签:
     9              作用:是给s:url或者s:a添加请求参数
    10              属性:
    11                  name:参数的名称
    12                  value:参数的值.它的取值是一个OGNL表达式.
    13          s:a标签:
    14              作用:和超链接标签是一样的。并且可以和s:url互换
    15     --%>
    16     <s:url action="action1" var="action1_url">
    17         <s:param name="param1" value="'hello'"></s:param>
    18     </s:url>
    19     <a href="<s:property value="#action1_url"/>">let me see see</a>
    20     
    21     
    22     <br/>
    23     <a href="${pageContext.request.contextPath}/action1.action">让我们看看</a>
    24     <br/>
    25     
    26     
    27     <s:a action="action1" namespace="">
    28         <s:param name="param1" value="'hello'"></s:param>
    29         去action1 看看
    30     </s:a>

    3.3、date标签

     1 <%--3、s:date --%>
     2     <font color="red">我们想要的输出结果是:2016-05-30  或者是 2016年05月30日</font><br/>
     3     <%--s:date标签:
     4             作用:格式化输出日期
     5             属性:
     6                 name:取值是一个OGNL表达式。指定的是要转换的日期对象
     7                 format:指定转换的格式
     8                 var:取值是一个普通的字符串。把var的值当做key,把转换好的日期当成value,存入contextMap中
     9      --%>
    10     <s:date name="birthday" format="yyyy-MM-dd" var="sbirthday"/>
    11     <%-- 
    12        DateFormat format = new SimpleDateFormat("yyyy年MM月dd日");
    13        String date = format.format(birthday);
    14        out.print(date);
    15     --%>
    16      
    17      
    18     <s:property value="#sbirthday"/>
  • 相关阅读:
    fusioncompute安装虚拟机的问题---如何扩容至5T 和 挂载Tools的解决方式
    接口请求返回状态码总结
    【内推】字节跳动
    RPA行业见解(一)
    消息中间件(一)MQ详解及四大MQ比较
    Springcloud学习
    常用加密算法
    Java实现token的生成与验证
    linux 系统下安装和卸载Node.js
    Linux安装Mysql
  • 原文地址:https://www.cnblogs.com/minihouseCoder/p/5589574.html
Copyright © 2011-2022 走看看