OGNL简介

OGNL


Ognl (Object-Graph Navigation Language)是对象图导航语言,用于访问一个容器中的对象的属性,调用对象的方法。主要是为了方便访问对象的属性和方法。

应用

  1. Struts2
  2. arthas中,命令参数

数据结构

OgnlContext是一个容器,本质是一个Map,key是String类型的值,value是对象。因此它具备所有Map的操作。

Ognl表达式,表达式由字符串组成,由Ognl解析,然后执行。

访问属性

OgnlContext中,分为root(根)节点和普通节点

实例属性

语法 #key.value
例子,ognlContext中有一个名为user的对象,它有一个name属性,那么访问该属性: #user.name

如果是根对象,不需要使用#

静态属性

语法 @全限定名@value
例子 @com.zzz.example.demo.Student@sex

赋值

使用=号即可

调用方法

实例方法

语法 #key.method(param1,param2...)
例子 #stu.print("hello")

静态方法

语法 @全限定名@method(param1,param2...)
例子 @com.zzz.example.demo.Student@method1("hello")

操作符

  1. 逗号操作符:方法调用分隔参数、集合中分隔item、其余情况一条语句中的范围值是最后一个逗号后的语句的值

集合操作

构造

  • 列表
{ null,"Untitled" }
  • Map
#{ "foo" : "foo value", "bar" : "bar value" }
  • 数组
new int[] { 1, 2, 3 }

访问

使用下标访问即可
语法 collection[index]
例子 listeners[0]

注意越界异常

投影

对集合中的所有元素执行相同的方法或者获取相同的属性,最后将结果组装为新的集合返回
语法 colltion.{ condition}
例子:

listeners.{delegate}

this在{}中表示当前变量

objects.{ #this instanceof String ? #this : #this.toString()}

选择

遍历集合,选择符合条件的对象,将结果组装成新的集合返回
语法 collection.{? condition}
例子

listeners.{? #this instanceof ActionListener}
选择第一个

collection.{? condition}[0] 但是选择的结果为空,然后抛越界异常
语法 collection.{^ condition} 将结果包装为集合返回

选择最后一个

collection.{$ condition} 将结果包装为集合返回

索引机制

  1. 如果是数组或者集合可以直接使用索引
myArray[0]
myList[0]
  1. 如果满足如下条件,表示这个属性拥有索引访问功能,可以这样使用
    someProperty[2]
public PropertyType[] getPropertyName();
public void setPropertyName(PropertyType[] anArray);
public PropertyType getPropertyName(int index);
public void setPropertyName(int index, PropertyType value);
  1. 如果满足如下条件,则可以这样使用
    session.attribute["foo"]
public PropertyType getPropertyName(IndexType index);
public void setPropertyName(IndexType index, PropertyType value);

例如

public Object getAttribute(String name);
public void setAttribute(String name, Object value)

官方文档

https://commons.apache.org/proper/commons-ognl/language-guide.html
本文简化了官方文档中的描述

例子

  1. 导包
 <dependency>
       <groupId>ognl</groupId>
        <artifactId>ognl</artifactId>
        <version>3.0.6</version>
</dependency>
package com.zzz.example.demo;

import lombok.AllArgsConstructor;
import lombok.Data;
import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;

/**
 * @author example
 * @description:
 * @date 2020/11/24 3:34 下午
 */
public class OgnlTest {

    //创建ognlContext
    public OgnlContext getOgnlContext() {
        OgnlContext context = (OgnlContext) Ognl.createDefaultContext(this);
        return context;
    }
    
    //map操作,访问对象
    public void testOgnlPropBase() throws OgnlException {
        OgnlContext ognlContext = this.getOgnlContext();
        ognlContext.put("a", "a");
        ognlContext.put("b", "b");
        ognlContext.setRoot("a");
        System.out.println(ognlContext.entrySet());
        Object expression = Ognl.parseExpression("#b");
        Object value = Ognl.getValue(expression, ognlContext, ognlContext.getRoot());
        printClassAndValue(value);


    }

    public void testOgnlPropOne() throws OgnlException {
        OgnlContext ognlContext = this.getOgnlContext();
        Pen pen = new Pen(3, "red");
        Stu stu = new Stu(18, "zuo", pen);
        ognlContext.put("pen", pen);
        ognlContext.put("stu", stu);
        ognlContext.put("test", "T");
        ognlContext.setRoot(pen);

        Object expression = Ognl.parseExpression("color");
        Object value = Ognl.getValue(expression, ognlContext, ognlContext.getRoot());
        printClassAndValue(value);
        //逗号
        expression = Ognl.parseExpression("#stu.name,#stu.age");
        value = Ognl.getValue(expression, ognlContext, ognlContext.getRoot());
        printClassAndValue(value);
    }

    public void testOgnlMethod() throws OgnlException {
        OgnlContext ognlContext = this.getOgnlContext();
        Pen pen = new Pen(3, "red");
        Stu stu = new Stu(18, "zuo", pen);
        ognlContext.put("pen", pen);
        ognlContext.put("stu", stu);
        ognlContext.put("test", "T");
        ognlContext.setRoot(this);

        Object expression = Ognl.parseExpression("#stu.print(\"hello\")");
        Object value = Ognl.getValue(expression, ognlContext, ognlContext.getRoot());
        System.out.println(value);

        expression = Ognl.parseExpression("#pen.getColor().(#this+\"hhhhh\")");
        value = Ognl.getValue(expression, ognlContext, ognlContext.getRoot());
        System.out.println(value);
    }

    public void testOgnlStaticProp() throws OgnlException {
        OgnlContext ognlContext = this.getOgnlContext();
        Pen pen = new Pen(3, "red");
        Stu stu = new Stu(18, "zuo", pen);
        ognlContext.put("pen", pen);
        ognlContext.put("stu", stu);
        ognlContext.put("test", "T");
        ognlContext.setRoot(this);
        Student student = new Student("liu", 20, pen);

        Object expression = Ognl.parseExpression("@com.zzz.example.demo.Student@sex");
        Object value = Ognl.getValue(expression, ognlContext, ognlContext.getRoot());
        printClassAndValue(value);

        expression=Ognl.parseExpression("@com.zzz.example.demo.Student@method1(\"hello\")");
        value=Ognl.getValue(expression,ognlContext,ognlContext.getRoot());
        printClassAndValue(value);

    }

    private void printClassAndValue(Object value) {
        if (value == null) {
            System.out.println("fuck null");
        }
        System.out.println(value.getClass() + " " + value);
    }

    private void testArray() throws OgnlException {
        OgnlContext ognlContext = this.getOgnlContext();
        Object expression = Ognl.parseExpression("#a=1,#b=2,#c=3,{#a,#b,#c}");
        Object value = Ognl.getValue(expression, ognlContext, ognlContext.getRoot());
        printClassAndValue(value);

    }

    public static void main(String[] args) throws OgnlException {
        OgnlTest ognlTest=new OgnlTest();
        ognlTest.testOgnlPropOne();

    }

    @Data
    @AllArgsConstructor
    class Stu {
        int age;
        String name;
        Pen pen;

        public void print(String fuck) {
            System.out.println(fuck + " " + age + name + pen);
        }
    }

    @Data
    @AllArgsConstructor
    class Pen {
        int len;
        String color;

        public String getColor() {
            return color;
        }
    }

}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值