zoukankan      html  css  js  c++  java
  • 对struts2的OGNL的理解

    OGNL:Object-Graph Navigation Language.对象图形化导航语言

    OGNL是集成进struts2框架中比較强大的技术有助于传输数据和类型转换,OGNL由表达式语言和类型装换器组成。

    表达式语言:
    我们已经在jsp表单input名和jsp标签使用该语言了.他用来绑定java端的数据属性和基于字符串的
    视图层表示.表达式语言甚至能够进行方法调用,目的就在于方便数据訪问.大多数时候OGNL表达式不
    须要转义,如需转义的话,须要用到%{表达式}符号.框架会把它依照表达式来处理而不是解释成字符
    串语义.

    以下是ognl的类图:


    说明:

    1.ValueStack是一个接口,在struts2中使用OGNL表达式实际上是使用实现了ValueStack接口的类OgnlValueStack,这个类是OgnlValueStack的基础。
    2.ValueStack贯穿整个action的生命周期。每个action实例都拥有一个ValueStack对象。当中保存了当前action对象和其它相关对象。(内部底层事实上是用ThreadLocal实现Action范围内数据共享)
    3.Struts2把ValueStack对象保存中名为struts.valueStack的request域中。

    以下是ValueStack的图解:


    说明:

    1,上图是ognl完整的数据结构图。能够清晰得看出数据的组成。
    2,Context中的_root和ValueStack中的root(对象栈)里的数据结构和值是一样的。
    3,这就意味着我们仅仅须要操作OgnlContext就能够完毕对数据的存和取的操作。
    4,ValueStack内部有两个逻辑的组成部分:
            a,ObjectStac
    Struts会把动作和相关的对象压入到ObjectStack中。
    b,ContextMap
    Struts会把一些映射关系压入到ContextMap中

    向map中存数据

    1, ServletActionContext.getRequest().setAttribute("req_username","req_username");
    ServletActionContext.getRequest().setAttribute("req_psw", "req_psw");
    ActionContext.getContext().getSession().put("session_username", "session_username");
    ActionContext.getContext().getSession().put("session_psw", "session_psw");

    2,ActionContext.getContext().put("data", "aaaaaaaaaaaaaaaaa");

    向值栈中存数据

    1,

    /*
     * 把对象放入到值栈中
     */
    //方法一:先得到root,把一个对象压入到root中
    ValueStack valueStack = ActionContext.getContext().getValueStack();
    valueStack.getRoot().add(new Person());
    valueStack.getRoot().add(new Student());

    2,

    /*
     * 方法二:先得到root。利用add(index,Object)把一个对象压入到root中
     * 这里index指的是集合中的位置
     */
    ValueStack valueStack = ActionContext.getContext().getValueStack();
    valueStack.getRoot().add(new Person());
    valueStack.getRoot().add(0, new Student());

    3,

    /*
     * 方法三:
     *   把一个键值对存放在对象栈中
     */

    ValueStack valueStack = ActionContext.getContext().getValueStack();
    valueStack.set("msg","msg_object");

    4,

    /*
     * 方法4
     * 利用ValueStack的push方法能够把一个对象直接压入对象栈的第一个位置
     */
    ValueStack valueStack = ActionContext.getContext().getValueStack();
    valueStack.push(new Person());

    OGNL Context图解:


    1,上图为OGNL Context的结构图
    2,当struts2接受一个请求时,会迅速创建ActionContext,ValueStack,action。然后把action压入到值栈中。

    所以action的实例变量能够被ognl訪问。所以利用ognl表达式能够訪问action。


    3,ActionContext是Action运行时的上下文。上下文能够看作是一个map容器(事实上我们这里的容器就是一个Map而已),存放Action在运行时须要用到的对象。而ServletActionContext(com.opensymphony.webwork. ServletActionContext),这个类直接继承了ActionContext,它提供了直接与JavaServlet相关对象訪问的功能。例如以下代码:

    Map session = ActionContext.getContext().getSession()。
    HttpSession session = ServletActionContext. getRequest().getSession(); 

    4,每次请求都会创建一个Action,运行Action之前都会创建新的ActionContext。ActionContext是线程安全的,也就是说在同一个线程里ActionContext里的属性是唯一的。这样Action就能够在多线程中使用。

    OGNL表达式:

    1,訪问OGNL上下文和action上下文,#相当于ActionContext.getContext();
    2,假设訪问的是map中的值而不是对象栈中的值,因为map中的数据不是根对象,所以在訪问时须要加入#前缀。


    Demo:

    在Action中:

    public String testScope() {
    // 把字符串"request_msg"放入到request域中
    ServletActionContext.getRequest().setAttribute("request_username","request_username");
    // 把字符串"session_msg"放入到session域中
    ServletActionContext.getRequest().getSession().setAttribute("session_username", "session_username");
    // 把字符串"application_msg"放入到application域中
    ServletActionContext.getServletContext().setAttribute("application_username", "application_username");
    return "ognl_scope";
    }

    页面中:

    ognl表达式关于scope(request,session,application)的输出<br>
    request:<s:property value="#request.request_username"/><br>
    session:<s:property value="#session.session_username"/><br>
    application:<s:property value="#application.application_username"/><br>

    3,OGNL会设定一个对象(root对象)。在struts2中根对象就是CompoundRoot。或者为OgnlValueStack中的root,通常被叫做ValueStack(值栈或者对象栈)。假设要訪问根对象的属性,则能够省略去#,直接訪问对象的属性就可以。

    Demo:

    在Action中:

    public String testObjectValue(){
    //得到ognl的上下文 
    ValueStack valueStack = ActionContext.getContext().getValueStack();
    valueStack.set("msg", "object_msg");
    return "ognl_objectstack";
    }

    在页面中:

    对象栈的内容:<s:property value="msg"/>
    //把对象栈中key值为msg的value的值输出

  • 相关阅读:
    C++ Primer 读书笔记 第六章
    C++ Primer 读书笔记 第十章
    面试题笔记
    C++ Primer 读书笔记 第八章
    ZedGraph源码学习(三)
    一个简单的代码生成器XML与XLST的应用测试。
    信息导到Execl上.
    SQL相关功能实现.
    ZedGraph源码学习(二)
    EXECL导入(检查服务器版本.包括NPOI方式导入.可以通过配置文件信息导入EXECL)代码记录下.
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5170521.html
Copyright © 2011-2022 走看看