• SSH学习-valueStack和OGNL表达式的使用


    Struts2的学习过程中,提到了valueStack和OGNL表达式,这两个是Struts2框架下的概念,这里参考老师授课和博客,进行简单记录和整理,后续有其他理解再添加上去。

    概念介绍

    (1)valueStack

    valueStack是值栈,是Struts2中用户共享数据的一种数据结构,其包含两个区域。

    Contents区域

    一个是Contents为栈结构(先进后出),也有博客称之为Root区域,主要是一个ArrayList,里面一般放置对象,获取这个区域的数据不需要加#。

    浏览器发送一个action请求到服务端filter,会在服务端创建一个action对象和valueStack,将请求所带的数据属性,在contents区域保存,默认值为数据类型初始值,如String类型属性为null,int类型为0,保存到contents区域,当action对象执行使用时,将调用拦截器,将请求中的数据取出来,初始化content区域的属性值,再将contents区域所保存的属性值,赋值给action对象的属性。当action请求结束返回字符串给result后,valueStack将销毁,这就是valueStack的生命周期。

    Context区域

    另外一个是Context为Map结构,里面放置的是web开发常用的对象数据引用,获取里面的数据需要加#对象名.属性名。常见的几种对象数据引用有(可以通过OGNL表达式的debug标签获取具体内容):

    1. Request

    2. Session

    3. Application

    4. Parameters

    5. attr

    JSP访问方式

    1. Contents区域使用OGNL表达式,EL表达式

    2. Context区域使用#Key的方式访问对应Value

    (2)OGNL表达式

    OGNL(Object-Graph Navigation Language),对象图导航语言,OGNL被Struts2整合后将变成它的一种标签,可以在JSP中使用,获取Contents区域的数值。此外它还有其他的强大功能,这里不做详细深究,其他可以参考文末博客。

    (3)生命周期

    当请求进入服务器端的filter,将创建valueStack对象,当请求结束,valueStack对象将被销毁。

    案例测试

    案例发送一个action请求到服务端,服务端action请求里有若干属性,在具体的执行方法里,采用两种方式获取valueStack,并往其中一个加入一条对象数据。在JSP页面使用OGNL表达式和EL表达式获取数据进行查看。

    (1)struts.xml中的配置

       <!-- 测试保存数据到valueStack中 -->
       <package name="test" namespace="/testValueStack" extends="struts-default">
         <action name="valueStack" class="testValueStack" method="doValueStack">
           <result name="success">
            /WEB-INF/msg.jsp
           </result>
         </action>
       </package>

    (2)将push到valueStack栈顶的对象所属类,其中包含message属性。

    package Entity;
    /**
     * 实体类,用于测试valueStack
     * @author yangchaolin
     */
    public class Person {
        
        private int id;
        private String name;
        private String message;//action请求也将有一个同名的属性message
        
        //创建无参数构造方法
        public Person() {
            super();
        }
    
        //创建有参数构造方法
        public Person(int id, String name, String message) {
            super();
            this.id = id;
            this.name = name;
            this.message = message;
        }
    
    ...省略get set方法
    
    }

    (3)action请求处理类,其中也包含一个message属性,跟action中的属性同名同类型。另外session中以key为name也放入了一条数据,其中Person对象中也有属性name。

    package Controller;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.apache.struts2.ServletActionContext;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Controller;
    
    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.util.ValueStack;
    
    import Entity.Person;
    
    /**
     * 控制器类
     * @author yangchaolin
     */
    @Controller
    @Scope("prototype")
    public class testValueStack {
        
        private String message;//Person实体类也有同名的属性message
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
        
        //具体实现方法
        public String doValueStack() {
            
            //给属性赋值
            message="我是action请求中的message";
            //创建person对象
            Person p=new Person(1,"我是Person对象中的name","我是Person对象中的message");
            //将person对象添加到valueStack中
            //action执行的所需的对象保存在ActionContext,如参数,session等
            
            //第一种获取valueStack的方式,根据ActionContext获得
            ActionContext ctx=ActionContext.getContext();
            ValueStack stack=ctx.getValueStack();
            stack.push(p);
            //第二种获取valueStack的方式,根据request对象获得
            HttpServletRequest request=ServletActionContext.getRequest();
            //key为struts.valueStack
            ValueStack stack_compare=(ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
            System.out.println("两种获取得到的valueStack相同吗?"+(stack==stack_compare));
            
            //session中也保存一条数据
            ctx.getSession().put("name", "我是Session中的name");
            
            return "success";
        }
    
    }

    (4)JSP页面,引入了Struts2的标签库,这样就可以使用OGNL表达式,EL表达式可以直接使用。

    <%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
    <!-- 引入Struts2中的标签库 -->
    <%@taglib prefix="s" uri="/struts-tags" %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>测试valueStack</title>
    </head>
    <body style="font-family:'微软雅黑';font-size:15px;">
         <h2>使用OGNL表达式</h2>
         <s:property value="message"></s:property><br>
         <!-- 获取同名message -->
         <s:property value="[1].message"></s:property><br>
         <s:property value="#session.name"></s:property><br><!-- 通过key获取 -->
          
         <h2>使用EL表达式</h2>    
         ${message}<br>
         ${name}   
         
         <!-- OGNL和EL表达式获取的都是contents区域中的值 -->
         
         <h2>输出valueStack中的数据,使用debug标签</h2>
         <s:debug></s:debug>
    </body>
    </html>

    测试结果

    (1)OGNL表达式和EL表达式获取值结果

     从测试结果可以看出来OGNL和EL表达式都可以从Contents区域获取数据,其中message都是Person对象中的message,而不是action对象中的message,是因为action中的message先存到了栈里面,使用表达式取值时是从栈顶往下扫描的,因此先扫描到了Person对象中的message后不再往下扫描,所以的两个表达式获取的都是Person对象中的。而使用EL表达式获取的也是Person对象中,而不是session中的,说明session中的值需要使用#Key的方式获取。

    此外两种获取valueStack的方式表明,两者获取的valueStack是一样的。

     (2)debug标签获取Contents和Context中的内容

    从结果可以直观的看到数据存储的地方,进而加强对valueStack和OGNL表达式的理解。可以看出session中的name,保存在了Context区域,只能通过#key的方式获取值。而message保存也是先保存了action中的message,后面执行了action中方法后,将Person对象push到栈顶后,才出现第二个message。如果要获取第二个message,需要在JSP中使用[1].message来得到。

    结论

    (1)valueStack是封装了action请求中数据的一种特殊数据结构,其中包含Contents区域和Context区域。

    (2)获取Contents区域需使用OGNL表达式或EL表达式,获取Context区域数据使用#Key方式

    (3)valueStack当action请求结束后将消失。

    参考博文:https://blog.csdn.net/qq_23853743/article/details/84664867

  • 相关阅读:
    windows phone 网络开发三部曲(一)各种包的各种抓法
    Windows phone UI虚拟化和数据虚拟化(二)
    Windows phone UI虚拟化和数据虚拟化(一)
    LongListSelector 控件 在 wp7 和wp8中的不同之处
    wp8 longlistselector 动态加载datatemplate
    解读Python发送邮件
    浅谈Python时间模块
    中文分词技术一:概念
    MySQL常用命令
    初步认识Hive
  • 原文地址:https://www.cnblogs.com/youngchaolin/p/10879348.html
Copyright © 2020-2023  润新知