zoukankan      html  css  js  c++  java
  • Struts2之Ognl

    上一篇算是看着学习了下ValueStack、ActionContext,如果还没明白他们之间是怎么回事,没关系,可以先学下Ognl,然后再回头看前面的可能就比较好理解了,我昨天也是一头雾水,现在把Ognl的学习了下,慢慢的有了感觉。

    一、概念

    OGNL表达式是(Object-Graph Navigation Language)是对象图形化导航语言。OGNL是一个开源的项目,struts2中默认使用OGNL表达式语言来显示数据。与serlvet中的el表达式的作用是一样的。OGNL表达式有下面以下特点:

    1.支持对象方法调用,例如:objName.methodName();
    2.支持类静态的方法调用和值访问,表达式的格式为
         @[类全名(包括包路经)]
         @[方法名 |  值名]
         例如:
             @java.lang.String@format('foo%s','bar')
             @tutorial.MyConstant@APP_NAME;
    3支持赋值操作和表达式串联,例如: 
           price=100, discount=0.8, calculatePrice(),这个表达式会返回80;
     4.访问OGNL上下文(OGNL context)和ActionContext
     5.操作集合对象

    二、实践

    这里定义了Address、User类

    package com.cyw.test;
    
    public class Address {
    
        public Address(String city, String street) {
            super();
            this.city = city;
            this.street = street;
        }
    
        private String city;
        public String getCity() {
            return city;
        }
        public void setCity(String city) {
            this.city = city;
        }
        public String getStreet() {
            return street;
        }
        public void setStreet(String street) {
            this.street = street;
        }
        private String street;
    }
    View Code
    package com.cyw.test;
    
    import java.util.Date;
    
    public class User {
        private String name;
        private int age;
        private Date birthDay;
        private Address address;
        public User(String name, int age, Date birthDay, Address address) {
            super();
            this.name = name;
            this.age = age;
            this.birthDay = birthDay;
            this.address = address;
        }
    
        public Address getAddress() {
            return address;
        }
        public void setAddress(Address address) {
            this.address = address;
        }
        public Date getBirthDay() {
            return birthDay;
        }
        public void setBirthDay(Date birthDay) {
            this.birthDay = birthDay;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
    
    
    }
    View Code
            Address address=new Address("深圳市","坂田新天下");
            User user=new User("cyw",25,new Date(),address);
            //获取javabean的属性值
            String name=(String) Ognl.getValue("name", new HashMap(), user)    ;
            System.out.println(name);
            //获取对象的属性值
            String city=(String) Ognl.getValue("address.city", new HashMap(), user)    ;
            System.out.println(city);
            //修改属性值
            name=(String) Ognl.getValue("name='cuiyw'", new HashMap(), user)    ;
            System.out.println(name);
            Ognl.getValue("setName('cyw')", new HashMap(), user)    ;
            //调用对象方法
            name=(String) Ognl.getValue("getName()", new HashMap(), user)    ;
            System.out.println(name);
            
            //访问静态方法 格式:@包名+类名@静态方法
            UUID randomUUID=(UUID)Ognl.getValue("@java.util.UUID@randomUUID()", new HashMap(), user)    ;
            System.out.println(randomUUID.toString());
            //访问静态变量格式:@包名+类名@静态变量名
            double pi=(double)Ognl.getValue("@java.lang.Math@PI", new HashMap(), user);
            System.out.println(pi);
            
            //操作索引数组元素
            int []array={1,2,3,4};
            int first= (int) Ognl.getValue("[0]", new HashMap(), array);
            System.out.println(first);
            
            //操作集合
            List<User> userList=new ArrayList<User>();
            userList.add(user);
            name = (String) Ognl.getValue("[0].name", new HashMap(), userList);
            System.out.println(name);
            
            //操作Map
            Map<String,String> map=new HashMap<String,String>();
            map.put("key1", "cui");
            map.put("key2", "yan");
            name = (String) Ognl.getValue("key1", new HashMap(), map);
            System.out.println(name);
            //创建list
            List<String> list=(List<String>)Ognl.getValue("{'cui','yan'}",  new HashMap(), new Object());
            System.out.println(list.get(0));
            
            //创建map
            map=(Map)Ognl.getValue("#{'name':'cui','name2':'yan'}",  new HashMap(), new Object());
            System.out.println(map.get("name"));

    三、ActionContext、ValueStack

    1.  ValueStack是一个接口,在struts2中使用OGNL表达式实际上是使用实现了ValueStack接口的类OgnlValueStack,这个类是OgnlValueStack的基础。
    2. ValueStack贯穿整个action的生命周期。每一个action实例都拥有一个ValueStack对象。其中保存了当前action对象和其他相关对象。
    3.  Struts2把ValueStack对象保存中名为struts.valueStack的request域中。

    ActionContext:

    OGNL中的上下文即struts2中的actionContext,OGNL中的root即struts2中的valueStack。

    充当OGNL的context,是action的上下文,也可以叫做action的数据中心,本质是一个map,在其中,所有的数据都存放在这里,那其中到底存放了哪些东西呢,actionContext中存放数据的方式又是怎样的?

    actionContext是一个map,所以其中都是以键值对的形式存储对象,如下图所示,

    request、session、application这种我们熟知的作用域,注意是作用域,而不是对象,

    paramters:这个是表单提交的参数,全部都会放到这个map中,

    attr(attributes):三个作用域所有的属性都会放在该map下,如果有重复的,那么以request域中的为准。

    VALUE_STACK:值栈,存放着valueStack对象,也就是说,通过ActionContext能够获取到valueStack。

    如果我们使用actionContext.put();  那么会将该键值对直接放入到ActionContext下

    ValueStack:值栈,本质是一个ArrayList,作用,充当ognl的root,给一次请求中共享数据的功能。

    root:源码中的名称为CompoundRoot,它也是一个栈,而每次值栈中入栈和出栈等操作其实就是对CompoundRoot进行对应的操作。

    Context:对actionContext的引用,也就是通过valueStack也能够获取到上下文,通过getContext();

    在我们访问一个action时,会将action加入到栈顶,也就是action会在CompoundRoot的栈顶,而我们提交的各种表单参数(充当了ognl表达式)会在valueStack从顶向下查找对应的属性进行赋值。这就是值栈的作用。

    参考:http://blog.csdn.net/v123411739/article/details/24052989

  • 相关阅读:
    安卓小助手
    位图切割器&位图裁剪器
    OAuth2.0 的简介
    多账户的统一登录方案
    常用的一些SQL语句
    SQL语句的优化
    SpringCloud简介与5大常用组件
    数据库为什么需要锁机制?有哪些锁机制?
    高并发下如何优化能避免服务器压力过大?
    Spring MVC 简介
  • 原文地址:https://www.cnblogs.com/5ishare/p/6636769.html
Copyright © 2011-2022 走看看