zoukankan      html  css  js  c++  java
  • OGNL

    1. /** 
    2.  * @author Downpour 
    3.  */  
    4. public class User {  
    5.       
    6.     private Integer id;  
    7.       
    8.     private String name;  
    9.       
    10.     private Department department = new Department();  
    11.       
    12.         // setter and getters  
    13. }  
    14.   
    15. //=========================================================================  
    16.   
    17. /** 
    18.  * @author Downpour 
    19.  */  
    20. public class Department {  
    21.       
    22.     private Integer id;  
    23.       
    24.     private String name;  
    25.           
    26.         // setter and getters  
    27. }  
    28.   
    29. //=========================================================================  
    30.   
    31. <form method="post" action="/struts-example/ognl.action">  
    32.     user name: <input type="text" name="user.name" value="downpour" />  
    33.     department name: <input type="text" name="department.name" value="dev" />  
    34.     <input type="submit" value="submit" />  
    35. </form>  
    36.   
    37. //=========================================================================  
    38.   
    39. /** 
    40.  * @author Downpour 
    41.  */  
    42. public class OgnlAction extends ActionSupport {  
    43.   
    44.     private static final Log logger = LogFactory.getLog(OgnlAction.class);  
    45.   
    46.     private User user;  
    47.       
    48.     private Department department;  
    49.       
    50.     /* (non-Javadoc) 
    51.      * @see com.opensymphony.xwork2.ActionSupport#execute() 
    52.      */  
    53.     @Override  
    54.     public String execute() throws Exception {  
    55.         logger.info("user name:" + user.getName());   // -> downpour  
    56.         logger.info("department name:" + department.getName());   // -> dev  
    57.         return super.execute();  
    58.     }  
    59.   
    60.     // setter and getters  
    61. }  
    62.   
    63. //=========================================================================  
    64.   
    65. user name: <s:property value="user.name" />  
    66. department name: <s:property value="department.name" />

    ValueStack —— 对OGNL的加强 

    细心的读者可能会发现,在上面的例子中,我们使用了不同的表达式,针对Action中的不同的Java对象进行设值。再结合上一讲我们所例举的OGNL的代码操作示例,我们有强烈的理由怀疑,Struts2在内部有可能执行了这样的操作,才使得页面到Action的设值工作顺利完成: 

    Java代码  收藏代码
    1. // "user.name" as OGNL expression, action as OGNL Root object  
    2. Ognl.setValue("user.name", action, "downpour");  
    3. Ognl.setValue("department.name", action, "dev");  



    如果这个怀疑是正确的,那么我们就能得出这样一个结论:Struts2的Action是OGNL操作的根对象。 

    这个结论是我们从现象上推出来的,至于它到底正确与否,我们之后可以通过源码分析来进行验证,在这里先卖一个关子,姑且认为它是正确的。不过这个结论对我们来说非常重要,因为这个结论Struts2的Tag,JSTL和Freemarker等表示层元素获取Action中变量的值打下了坚实的基础。 

    在Struts2(XWork)中,不仅把Action作为OGNL操作的根对象,作为对OGNL的扩展,它还引入了一个ValueStack的概念。这个概念代表了什么呢?还是让我们看看Struts2的Reference怎么说: 

    Struts2 Reference 写道
    The biggest addition that XWork provides on top of OGNL is the support for the ValueStack. While OGNL operates under the assumption there is only one "root", XWork's ValueStack concept requires there be many "roots".


    很明显,ValueStack依照它的结构和作用,至少为我们提供两大特性: 

    1. ValueStack是一个堆栈结构,堆栈中的每个元素对于OGNL操作来说,都被看作是根对象。 

    2. 由于ValueStack是一个堆栈结构,所以其中的元素都是有序的,对于某个OGNL表达式来说,OGNL将自堆栈顶部开始查找,并返回第一个符合条件的对象元素。
     

    这里我们有必要对第二点啰嗦几句,举个具体的例子来说(这个例子同样摘自Struts2的Reference):如果在ValueStack中有2个对象,分别是“动物”和“人”,这两个对象都具备一个属性,叫做name,而“动物”还有一个属性叫species,“人”还有个属性叫salary。其中,“动物”对象在ValueStack的栈顶,而“人”这个对象在栈底。那么看看下面的OGNL表达式将返回什么? 

    Java代码  收藏代码
    1. species    // call to animal.getSpecies()  
    2. salary     // call to person.getSalary()  
    3. name       // call to animal.getName() because animal is on the top  



    对于name这个属性,返回的将是“动物”的name,因为“动物”在栈顶,会被先匹配到OGNL的表达式。但是有的时候,你可能需要访问“人”的name属性,怎么办呢?你可以通过下面的方法: 

    Java代码  收藏代码
    1. [0].name   // call to animal.getName()  
    2. [1].name   // call to person.getName()  



    Struts2中的OGNL上下文环境 

    有了ValueStack,我们再来仔细研究一下Struts2中OGNL的上下文环境。 

    Struts2 Reference 写道
    The framework sets the OGNL context to be our ActionContext, and the value stack to be the OGNL root object. (The value stack is a set of several objects, but to OGNL it appears to be a single object.) Along with the value stack, the framework places other objects in the ActionContext, including Maps representing the application, session, and request contexts. These objects coexist in the ActionContext, alongside the value stack (our OGNL root)



    也就是说,ActionContext是Struts2中OGNL的上下文环境。它维护着一个Map的结构,下面是这个结构的图示: 

     

    其中,ValueStack是这个上下文环境中的根对象,而除了这个根对象以外,Struts2还在这个上下文环境中放了许多额外的变量,而这些变量多数都是被XWork封装过的Servlet对象,例如request,session,servletContext(application)等,这些对象都被封装成Map对象,随着ActionContext作用于整个Action执行的生命周期中。 

    在这里,或许有些读者会提出问题来,为什么好好的Servlet对象要在这里被封装成Map对象呢?我想原因可能有以下两个: 

    1. 对Struts2的Action彻底屏蔽Servlet容器,从而无需再使用底层Servlet API进行编程。你所面对的,将永远是一个又一个的Java对象。 

    2. 便于各种View技术,例如JSP,Freemarker,Velocity等对ValueStack中上下文环境,尤其是Servlet对象中的数据进行读取。试想,如果在这里不将HttpServletRequest,HttpSession等Servlet对象转化成Map,那么我们将很难通过OGNL表达式,对这些Servlet对象中的值进行读取。
     

    Struts2中使用OGNL进行计算 

    取值计算 

    有了上面的这些知识,我们就能非常容易的理解在Struts2中如何使用OGNL进行取值计算。 

    提问:在Struts2中,如何使用自身的Tag读取Action中的变量? 

    Struts2自身的Tag会根据value中的OGNL表达式,在ValueStack中寻找相应的对象。因为action在ValueStack的顶部,所以默认情况下,Struts2的Tag中的OGNL表达式将查找action中的变量。请注意,value中的内容直接是OGNL表达式,无需任何el的标签包装。 

    设值计算 

    Struts2中使用OGNL进行设值计算,就是指View层传递数据到Control层,并且能够设置到相应的Java对象中。这个过程从逻辑上说需要分成两步来完成: 

    1. 对于每个请求,都建立一个与相应Action对应的ActionContext作为OGNL的上下文环境和ValueStack,并且把Action压入ValueStack 

    2. 在请求进入Action代码前,通过某种通用的机制,搜集页面上传递过来的参数,并调用OGNL相关的代码,对Action进行设值。 

    上面的第一个步骤,在处理URL请求时完成,而第二个步骤,则涉及到另外一个XWork的核心知识:拦截器。所以有关Struts2使用OGNL进行设值计算的详细分析,将会在拦截器章节具体给出。 

  • 相关阅读:
    SQL Server 通用分页存储过程
    SQL 分页通用存储过程
    python 获取本机IP的三种方式
    Python代码打印出9*9 九九乘法表
    python进程.线程和协程的总结
    5.__魔法方法__开会喽
    css干货部分
    html干货部分
    pyinstaller 打包exe可执行文件
    3_3.黏包现象
  • 原文地址:https://www.cnblogs.com/6zhi/p/5943117.html
Copyright © 2011-2022 走看看