目录
- 一、简介
- 二、快速入门
- 三、详细使用
- 3.0 Ognl操作
- 3.1 基本数据类型
- 3.2 对象类型
- 3.3 List集合
- 3.4 Set集合
- 3.5 Map集合
- 3.6 数组
- 3.7 静态调用
- 3.8 算术运算
- 3.9 逻辑运算
- 3.10 同时执行多个表达式
- 3.11 位运算
一、简介
OGNL(Object-Graph Navigation Language的简称),对象图导航语言,通过表达式来实现:
- 设置/获取Java对象及属性
- 集合操作
- 对象方法调用
- 静态方法调用
- 表达式串联
许多常用框架都集成了ognl,如mybatis、struts、spring、arthas等。
本文详细总结了Ognl的大部分使用场景,阅读前请收藏。
这里仅以java环境下的代码进行演示。
二、快速入门
- 引入依赖
<dependency>
<groupId>ognl</groupId>
<artifactId>ognl</artifactId>
<version>3.3.0</version>
</dependency>
- 快速入门
//1.创建Ognl上下文(本质是map,有一个特殊的key用来放root,普通key直接put)
OgnlContext ognlContext = new OgnlContext();
//2.构建表达式
//访问root对象相关(不以#开头表示直接访问根对象)
Object rootExp1 = Ognl.parseExpression("orderNo");
Object rootExp2 = Ognl.parseExpression("address.city");
//访问普通对象相关(以#开头表示先去普通对象找,如果找不到再去根对象中去找)
Object normalExp1 = Ognl.parseExpression("#key1");
Object normalExp2 = Ognl.parseExpression("#key2");
//静态方法调用
Object methodCallExp = Ognl.parseExpression("@java.math.BigDecimal@valueOf(12)");
//3.将要解析的对象及根对象放入Ognl上下文(如果是静态方法调用可以不放)
//放入根对象
ognlContext.setRoot(buildOrder());
//放入普通对象
ognlContext.put("key1","val1");
ognlContext.put("key2","val2");
//4.获取对应属性或调用方法
Object rootExpVal1 = Ognl.getValue(rootExp1, ognlContext, ognlContext.getRoot());
System.out.println("rootExpVal1:"+rootExpVal1);
Object rootExpVal2 = Ognl.getValue(rootExp2, ognlContext, ognlContext.getRoot());
System.out.println("rootExpVal2:"+rootExpVal2);
Object normalExpVal1 = Ognl.getValue(normalExp1, ognlContext, ognlContext.getRoot());
System.out.println("normalExpVal1:"+normalExpVal1);
Object normalExpVal2 = Ognl.getValue(normalExp2, ognlContext, ognlContext.getRoot());
System.out.println("normalExpVal2:"+normalExpVal2);
Object methodCallExpVal = Ognl.getValue(methodCallExp, ognlContext, ognlContext.getRoot());
System.out.println("methodCallExpVal:"+methodCallExpVal);
- 核心API理解
1、表达式(Expression):表达式是整个OGNL的核心,OGNL会根据表达式去对象中取值。表达式就是一个带有语法含义的字符串,这个字符串规定了操作的类型和操作的内容。
2、根对象(Root):Root对象可以理解为OGNL的操作对象,表达式规定了“做什么”,而Root对象规定了“对谁操作”。OGNL称为对象图导航语言,所谓对象图,就是可以以任意一个对象为根,通过OGNL可以访问与这个对象关联的其他对象。
3、上下文环境(Context):设置了Root对象和普通对象,是OGNL表达式操作的上下文环境(Context)。上下文环境Context是一个Map类型的对象,可以放根对象和普通对象。
三、详细使用
创建测试实体
@Data
public class Order{
private String orderNo;
private String comment;
private Long buyer;
private BigDecimal payAmt;
private Address address;
private List<Item> items;
private Set<Integer> tags;
private String[] promotionTypes;
private Map<String,Object> orderContext;
public static Order parse(String str){
return JSON.parseObject(str, Order.class);
}
}
@Data
public class Item{
private String itemName;
private Long itemId;
private Long quantity;
}
@Data
public class Address{
private String province;
private String city;
private String zone;
private String mobile;
private String name;
}
构建实体的工具类
public static Order buildOrder() {
Order order = new Order();
order.setOrderNo("202306010013600221");
order.setBuyer(1160397L);
order.setComment("请务必发顺丰");
order.setPayAmt(new BigDecimal("12.0"));
order.setTags(Sets.newHashSet(1,2,3));
order.setPromotionTypes(new String[]{"VIP","COUPON","FULL_REDUCE"});
order.setAddress(buildAddress());
order.setItems(buildItems());
order.setOrderContext(buildContext());
return order;
}
private static Address buildAddress() {
Address address = new Address();
address.setProvince("上海市");
address.setCity("上海市");
address.setZone("浦东新区");
address.setMobile("17611112222");
address.setName("Mr.Wang");
return address;
}
private static List<Item> buildItems() {
List<Item> items = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
Item item = new Item();
item.setItemId(10117000120L+i);
item.setItemName("香草冰淇淋"+i);
item.setQuantity((long) i);
items.add(item);
}
return items;
}
protected static Item buildItem(int i) {
Item item = new Item();
item.setItemId(10117000120L+i);
item.setItemName("香草冰淇淋"+i);
item.setQuantity((long) i);
return item;
}
private static Map<String,Object> buildContext() {
Map<String,Object> map = new HashMap<>();
map.put("device","H5");
Map<String,String> source = new HashMap<>();
source.put("orderFrom","1");
source.put("distId","1160397");
map.put("source",source);
map.put("expire",3600);
return map;
}
根据表达式的操作对象和场景不同,分为以下几类
3.0 Ognl操作
/**
* 往上下文中添加值,并返回
*/
@Test
public void putInOgnlContext() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
Object value = Ognl.getValue("#value1=1+1", ognlContext,ognlContext.getRoot());
System.out.println("value:"+value);
System.out.println(ognlContext.get("value1"));
}
3.1 基本数据类型
一般都是用来判断相等、比较(比较参考后面的逻辑运算)
@Test
public void longEquals() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
ognlContext.setRoot(buildOrder());
Object value = Ognl.getValue("buyer == 1160397", ognlContext, ognlContext.getRoot());
Assert.assertTrue((Boolean) value);
Object value2 = Ognl.getValue("buyer == 1160397L", ognlContext, ognlContext.getRoot());
Assert.assertTrue((Boolean) value2);
}
@Test
public void strEquals() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
ognlContext.setRoot(buildOrder());
Object value = Ognl.getValue("comment == '请务必发顺丰'", ognlContext, ognlContext.getRoot());
Assert.assertTrue((Boolean) value);
Object value2 = Ognl.getValue("comment.equals('请务必发顺丰')", ognlContext, ognlContext.getRoot());
Assert.assertTrue((Boolean) value2);
}
3.2 对象类型
/**
* 创建对象
*/
@Test
public void generate() throws OgnlException, ClassNotFoundException {
//调用new创建
Object newObject = Ognl.getValue("new com.wsl.util.ognl.dto.Order()", null);
System.out.printf("newObject,class:%s,toString:%s%n",newObject.getClass(), JSON.toJSONString(newObject));
//JSON.parseObject有重载方法想办法绕过重载:写个专门的工具方法调用JSON.parseObject生成
Object deserializeObject3 = Ognl.getValue("@com.wsl.util.ognl.dto.Order@parse(\"{'orderNo':'1111','comment':'不要香菜'}\")", new OgnlContext());
System.out.printf("deserializeObject3,class:%s,toString:%s%n",deserializeObject3.getClass(),JSON.toJSONString(deserializeObject3));
}
/**
* 获取简单属性
*/
@Test
public void getAttr() throws OgnlException {
Order order = buildOrder();
String comment = (String) Ognl.getValue("comment", order);
System.out.println("comment:"+comment);
}
/**
* 获取嵌套属性
*/
@Test
public void getNestedAttr() throws OgnlException {
Order order = buildOrder();
String mobile = (String) Ognl.getValue("address.mobile", order);
System.out.println("mobile:"+mobile);
}
/**
* 调用属性的方法,不能省略方法的括号,有参方法也可以调用
*/
@Test
public void callAttrMethod() throws OgnlException {
Order order = buildOrder();
int length = (int) Ognl.getValue("address.mobile.length()", order);
System.out.println("mobile.length:"+length);
boolean startWith = (boolean) Ognl.getValue("address.mobile.startsWith(\"176\")", order);
System.out.println("mobile.startWith 176:"+startWith);
}
/**
* 设置属性
*/
@Test
public void setAttr() throws OgnlException {
Order order = buildOrder();
Ognl.setValue("comment", order,"不要加香菜啊");
System.out.println("after setValue:"+ order.getComment());
}
/**
* 获取class
*/
@Test
public void getClassType() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
ognlContext.setRoot(buildOrder());
System.out.println(Ognl.getValue("address.getClass()",ognlContext,ognlContext.getRoot()));
System.out.println(Ognl.getValue("@com.wsl.util.ognl.dto.Address@class",ognlContext,ognlContext.getRoot()));
System.out.println(Ognl.getValue("@java.lang.Class@forName(\"com.wsl.util.ognl.dto.Address\")",ognlContext,ognlContext.getRoot()));
}
3.3 List集合
注意:表达式{}只能被反序列化为ArrayList,不能转换为Set,Array
/**
* 基于常量构建
*/
@Test
public void generate() throws OgnlException {
//调用new创建
Object newList = Ognl.getValue("new java.util.ArrayList()", null);
System.out.printf("newList,class:%s,toString:%s%n",newList.getClass(),JSON.toJSONString(newList));
//通过json格式反序列化创建
System.out.println(Ognl.getValue("{}", (Object)null, ArrayList.class));
Object deserializeList = Ognl.getValue("{'aa', 'bb', 'cc', 'dd'}", (Object)null, ArrayList.class);
System.out.printf("deserializeList,class:%s,toString:%s%n",deserializeList.getClass(),JSON.toJSONString(deserializeList));
Object buildAndIndex = Ognl.getValue("{'aa', 'bb', 'cc', 'dd'}[2]", null);
System.out.println("buildAndIndex:"+buildAndIndex);
//通过Lists工具类创建
Object guavaLists = Ognl.getValue("@com.google.common.collect.Lists@newArrayList('aa', 'bb', 'cc', 'dd')", (Object)null, ArrayList.class);
System.out.printf("guavaLists,class:%s,toString:%s%n",guavaLists.getClass(),JSON.toJSONString(guavaLists));
}
/**
* 构建的元素可以基于方法调用或现有上下文构建
*/
@Test
public void generate2() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
ognlContext.setRoot(buildOrder());
Object value = Ognl.getValue("{comment,new java.util.Random().nextInt(10),orderNo,items}", ognlContext, ognlContext.getRoot());
System.out.println(value);
}
/**
* 相当于集合的stream.map.collectToList,返回值是ArrayList
* 格式: collection.{? 过滤条件},过滤条件中将元素作为root的表达式
*/
@Test
public void filter() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
ognlContext.put("strList", Lists.newArrayList("a","bb","ccc","dddd","eeeee"));
//基本类型集合
Object filterList = Ognl.getValue("#strList.{? length() > 2}", ognlContext, buildOrder());
System.out.println("filterList:"+ JSON.toJSONString(filterList));
//对象集合
Object filterList2 = Ognl.getValue("items.{? quantity > 2}", ognlContext, buildOrder());
System.out.println("filterList2:"+ JSON.toJSONString(filterList2));
}
/**
* 过滤后取满足条件的第一个
* 格式:collection.{^ 过滤条件},过滤条件中将元素作为root的表达式
*/
@Test
public void filterAndPeekFirst() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
ognlContext.put("strList", Lists.newArrayList("a","bb","ccc","dddd","eeeee"));
//基本类型集合
Object filterList = Ognl.getValue("#strList.{^ length() > 2}", ognlContext, buildOrder());
System.out.println("filterList:"+ JSON.toJSONString(filterList));
//对象集合
Object filterList2 = Ognl.getValue("items.{^ quantity > 2}", ognlContext, buildOrder());
System.out.println("filterList2:"+ JSON.toJSONString(filterList2));
}
/**
* 过滤后取满足条件的最后一个
* 格式:collection.{^ 过滤条件},过滤条件中将元素作为root的表达式
*/
@Test
public void filterAndPeekLast() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
ognlContext.put("strList", Lists.newArrayList("a","bb","ccc","dddd","eeeee"));
//基本类型集合
Object filterList = Ognl.getValue("#strList.{$ length() > 2}", ognlContext, buildOrder());
System.out.println("filterList:"+ JSON.toJSONString(filterList));
//对象集合
Object filterList2 = Ognl.getValue("items.{$ quantity > 2}", ognlContext, buildOrder());
System.out.println("filterList2:"+ JSON.toJSONString(filterList2));
}
/**
* 相当于集合的stream.map.collectToList,返回值是ArrayList
* 格式:collection.{function},过滤条件中将元素作为root的表达式
*/
@Test
public void mapToCollection() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
ognlContext.put("strList", Lists.newArrayList("a","bb","ccc","dddd","eeeee"));
//转化
Object mapList = Ognl.getValue("#strList.{length()}", ognlContext, buildOrder());
System.out.println("mapList:"+ JSON.toJSONString(mapList));
}
/**
* 获取元素
*/
@Test
public void getByIndex() throws OgnlException {
Order order = buildOrder();
Item item2 = (Item) Ognl.getValue("items[1]", order);
System.out.println("item2:"+ JSON.toJSONString(item2));
Item item1 = (Item) Ognl.getValue("items.get(0)", order);
System.out.println("item1:"+ JSON.toJSONString(item1));
}
/**
* 调用List的方法
*/
@Test
public void callListMethod() throws OgnlException {
Order order = buildOrder();
Object size = Ognl.getValue("items.size()", order);
System.out.println("size:"+ size);
Object isEmpty = Ognl.getValue("items.isEmpty()", order);
System.out.println("isEmpty:"+ isEmpty);
Object removeResult = Ognl.getValue("items.remove(0)", order);
System.out.println("removeResult:"+ removeResult+",after size:"+order.getItems().size());
Object clearResult = Ognl.getValue("items.clear()", order);
System.out.println("clearResult:"+ clearResult+",after size:"+order.getItems().size());
}
/**
* 替换元素
*/
@Test
public void replaceElement() throws OgnlException {
Order order = buildOrder();
Ognl.setValue("items[0]", order,buildItem(6));
System.out.println("afterValue:"+ order.getItems().get(0));
}
3.4 Set集合
/**
* 构建
*/
@Test
public void generate() throws OgnlException {
//调用new创建
Object newSet = Ognl.getValue("new java.util.HashSet()", null);
System.out.printf("newSet,class:%s,toString:%s%n",newSet.getClass(), JSON.toJSONString(newSet));
//不能通过json格式反序列化创建
//能通过Sets工具类创建
Object guavaSets = Ognl.getValue("@com.google.common.collect.Sets@newHashSet('aa', 'bb', 'cc', 'dd')", (Object)null, HashSet.class);
System.out.printf("guavaSets,class:%s,toString:%s%n",guavaSets.getClass(),JSON.toJSONString(guavaSets));
}
/**
* 相当于集合的stream.map.collectToList,返回值是ArrayList
* 格式: collection.{? 过滤条件},过滤条件中将元素作为root的表达式
*/
@Test
public void filter() throws OgnlException {
Object filterList = Ognl.getValue("tags.{? intValue() > 1}", new OgnlContext(), buildOrder());
System.out.printf("filterSet,class:%s,collection:%s%n",filterList.getClass(),JSON.toJSONString(filterList));
}
/**
* 过滤后取满足条件的第一个
* 格式:collection.{^ 过滤条件},过滤条件中将元素作为root的表达式
*/
@Test
public void filterAndPeekFirst() throws OgnlException {
Object filterSet = Ognl.getValue("tags.{^ intValue() > 1}", new OgnlContext(), buildOrder());
System.out.printf("filterSet,class:%s,collection:%s%n",filterSet.getClass(),JSON.toJSONString(filterSet));
}
/**
* 过滤后取满足条件的最后一个
* 格式:collection.{^ 过滤条件},过滤条件中将元素作为root的表达式
*/
@Test
public void filterAndPeekLast() throws OgnlException {
Object filterSet = Ognl.getValue("tags.{$ intValue() > 1}", new OgnlContext(), buildOrder());
System.out.printf("filterSet,class:%s,collection:%s%n",filterSet.getClass(),JSON.toJSONString(filterSet));
}
/**
* 相当于集合的stream.map.collectToList,返回值是ArrayList
* 格式:collection.{function},过滤条件中将元素作为root的表达式
*/
@Test
public void mapToCollection() throws OgnlException {
Object filterSet = Ognl.getValue("tags.{intValue()+1}", new OgnlContext(), buildOrder());
System.out.printf("filterSet,class:%s,collection:%s%n",filterSet.getClass(),JSON.toJSONString(filterSet));
}
/**
* 常调用的方法
*/
@Test
public void callSetMethod() throws OgnlException {
Order order = buildOrder();
Object size = Ognl.getValue("items.size()", order);
System.out.println("size:"+ size);
Object isEmpty = Ognl.getValue("items.isEmpty()", order);
System.out.println("isEmpty:"+ isEmpty);
Object clearResult = Ognl.getValue("items.clear()", order);
System.out.println("clearResult:"+ clearResult+",after size:"+order.getItems().size());
}
3.5 Map集合
/**
* 构建
*/
@Test
public void generate() throws OgnlException {
//调用new创建
Object newMap = Ognl.getValue("new java.util.HashMap()", null);
System.out.printf("newMap,class:%s,toString:%s%n",newMap.getClass(), JSON.toJSONString(newMap));
//通过json格式反序列化创建
Object deserializeMap = Ognl.getValue("#{'k1':'v1','k2':'v2'}", (Object)null, HashMap.class);
System.out.printf("deserializeMap,class:%s,toString:%s%n",deserializeMap.getClass(),JSON.toJSONString(deserializeMap));
Object buildAndIndex = Ognl.getValue("#{'k1':'v1','k2':'v2'}['k1']", null);
System.out.println("buildAndIndex:"+buildAndIndex);
}
/**
* 获取元素方法:
* 1.当成对象使用,key就是属性
* 2.当前map使用,调用get(key)方法
*/
@Test
public void getByKey() throws OgnlException {
Order order = buildOrder();
Object val1 = Ognl.getValue("orderContext.device", order);
System.out.println("orderContext.device:"+ val1);
Object val11 = Ognl.getValue("orderContext.get(\"device\")", order);
System.out.println("orderContext.device:"+ val11);
Object val2 = Ognl.getValue("orderContext.source.orderFrom", order);
System.out.println("orderContext.source.orderFrom:"+ val2);
Object val22 = Ognl.getValue("orderContext.get(\"source\").get(\"orderFrom\")", order);
System.out.println("orderContext.source.orderFrom:"+ val22);
}
/**
* 调用Map的方法
*/
@Test
public void callMapMethod() throws OgnlException {
Order order = buildOrder();
Object size = Ognl.getValue("orderContext.size()", order);
System.out.println("size:"+ size);
Object isEmpty = Ognl.getValue("orderContext.isEmpty()", order);
System.out.println("isEmpty:"+ isEmpty);
Object containsKey = Ognl.getValue("orderContext.containsKey(\"OrderFrom\")", order);
System.out.println("containsKey:"+ containsKey);
Object keySet = Ognl.getValue("orderContext.keySet()", order);
System.out.println("keySet:"+ keySet);
Object values = Ognl.getValue("orderContext.values()", order);
System.out.println("values:"+ values);
Object putResult = Ognl.getValue("orderContext.put(\"new\",\"val\")", order);
System.out.println("putResult:"+ putResult+",after keySets:"+order.getOrderContext().keySet());
Object removeResult = Ognl.getValue("orderContext.remove(\"new\")", order);
System.out.println("removeResult:"+ removeResult+",after keySets:"+order.getOrderContext().keySet());
Object clearResult = Ognl.getValue("orderContext.clear()", order);
System.out.println("clearResult:"+ clearResult+",after size:"+order.getOrderContext().size());
}
3.6 数组
/**
* 构建
*/
@Test
public void generate() throws OgnlException {
//调用new创建
Object newArr = Ognl.getValue("new String[5]", null);
System.out.printf("newArr,class:%s,toString:%s%n",newArr.getClass(), JSON.toJSONString(newArr));
//通过匿名调用构建
Object newArr2 = Ognl.getValue("new String[]{'aa', 'bb', 'cc', 'dd'}", null);
System.out.printf("newArr,class:%s,toString:%s%n",newArr2.getClass(), JSON.toJSONString(newArr2));
//不能通过json格式反序列化创建
}
/**
* 获取元素
*/
@Test
public void getByIndex() throws OgnlException {
Order order = buildOrder();
Object promotionTypes2 = Ognl.getValue("promotionTypes[1]", order);
System.out.println("promotionTypes2:"+ promotionTypes2);
}
/**
* 获取length
*/
@Test
public void length() throws OgnlException {
Order order = buildOrder();
Object length = Ognl.getValue("promotionTypes.length", order);
System.out.println("length:"+ length);
}
3.7 静态调用
调用静态方法或访问静态属性
/**
* 静态方法调用,格式为:@class@method(params)
* 1.class必须为全路径
* 2.可以有参数,也可以无参数,根据方法实际情况
* 3.如果表达式很复杂可以调用自己写的static方法(参数简化为基本类型)
*/
@Test
public void callStaticMethod() throws OgnlException {
BigDecimal bigDecimal = (BigDecimal) Ognl.getValue("@java.math.BigDecimal@valueOf(12)", null);
System.out.println("bigDecimal:"+bigDecimal);
Object random = Ognl.getValue("@java.lang.Math@random()", null);
System.out.println("random:"+random);
}
/**
* 静态属性获取,格式为:@class@field
* class必须为全路径
*/
@Test
public void staticField() throws OgnlException {
System.out.println(Ognl.getValue("@java.lang.System@out",null));
Ognl.getValue("@java.lang.System@out.print(\"print\")",null);
}
3.8 算术运算
/**
* 表达式中可以直接运用加减乘除等
*/
@Test
public void cac() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
System.out.println(Ognl.getValue("1+1", ognlContext,ognlContext.getRoot()));
System.out.println(Ognl.getValue("2-1", ognlContext,ognlContext.getRoot()));
System.out.println(Ognl.getValue("2*5", ognlContext,ognlContext.getRoot()));
System.out.println(Ognl.getValue("10/5", ognlContext,ognlContext.getRoot()));
System.out.println(Ognl.getValue("10%3", ognlContext,ognlContext.getRoot()));
}
3.9 逻辑运算
/**
* 条件
*/
@Test
public void and() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
ognlContext.setRoot(buildOrder());
Object and1 = Ognl.getValue("items.size() > 10 and tags.size() > 2", ognlContext,ognlContext.getRoot());
System.out.println("and1:"+and1);
Object and2 = Ognl.getValue("items.size() > 10 && tags.size() > 2", ognlContext,ognlContext.getRoot());
System.out.println("and2:"+and2);
}
@Test
public void or() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
ognlContext.setRoot(buildOrder());
Object or = Ognl.getValue("items.size() > 10 or tags.size() > 2", ognlContext,ognlContext.getRoot());
System.out.println("or:"+or);
Object or2 = Ognl.getValue("items.size() > 10 || tags.size() > 2", ognlContext,ognlContext.getRoot());
System.out.println("or2:"+or2);
}
/**
* 内部表达式用括号括起来
*/
@Test
public void not() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
ognlContext.setRoot(buildOrder());
System.out.println(Ognl.getValue("!(items.size() > 10)", ognlContext,ognlContext.getRoot()));
System.out.println(Ognl.getValue("not (items.size() > 10)", ognlContext,ognlContext.getRoot()));
}
@Test
public void instanceOf() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
ognlContext.setRoot(buildOrder());
Object instanceOf = Ognl.getValue("address instanceof Object", ognlContext,ognlContext.getRoot());
System.out.println("instanceOf:"+instanceOf);
}
/**
* 判断元素是否在集合或数组当中,一般用户基本元素
*/
@Test
public void in() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
ognlContext.setRoot(buildOrder());
System.out.println(Ognl.getValue("1 in tags", ognlContext,ognlContext.getRoot()));
System.out.println(Ognl.getValue("'VIP' in promotionTypes", ognlContext,ognlContext.getRoot()));
System.out.println(Ognl.getValue("1 in items.{quantity}", ognlContext,ognlContext.getRoot()));
}
@Test
public void compare() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
ognlContext.put("num",10);
Assert.assertTrue((Boolean) Ognl.getValue("#num == 10", ognlContext, ognlContext.getRoot()));
Assert.assertTrue((Boolean) Ognl.getValue("#num eq 10", ognlContext, ognlContext.getRoot()));
Assert.assertTrue((Boolean) Ognl.getValue("#num != 9", ognlContext, ognlContext.getRoot()));
Assert.assertTrue((Boolean) Ognl.getValue("#num neq 9", ognlContext, ognlContext.getRoot()));
Assert.assertTrue((Boolean) Ognl.getValue("#num > 0", ognlContext, ognlContext.getRoot()));
Assert.assertTrue((Boolean) Ognl.getValue("#num gt 0", ognlContext, ognlContext.getRoot()));
Assert.assertTrue((Boolean) Ognl.getValue("#num >= 0", ognlContext, ognlContext.getRoot()));
Assert.assertTrue((Boolean) Ognl.getValue("#num gte 0", ognlContext, ognlContext.getRoot()));
Assert.assertFalse((Boolean) Ognl.getValue("#num < 0", ognlContext, ognlContext.getRoot()));
Assert.assertFalse((Boolean) Ognl.getValue("#num lt 0", ognlContext, ognlContext.getRoot()));
Assert.assertFalse((Boolean) Ognl.getValue("#num <= 0", ognlContext, ognlContext.getRoot()));
Assert.assertFalse((Boolean) Ognl.getValue("#num lte 0", ognlContext, ognlContext.getRoot()));
}
3.10 同时执行多个表达式
一个表达式中执行多个表达式语句,多个表达式要逗号隔开
整个表达式的返回值取最后一个表达式的值
/**
* 执行表达式列表:
* 1.赋值value1到上下文中(获取系统变量1),表达式为静态方法调用
* 2.赋值value2到上下文中(获取系统变量2),表达式为静态方法调用
* 3.构建一个集合,元素为上下文中的value1,value2
*/
@Test
public void multiGetByStaticMethod() throws OgnlException {
Object value = Ognl.getValue("#value1=@System@getProperty(\"java.home\"), #value2=@System@getProperty(\"java.runtime.name\"),{#value1, #value2}", null);
System.out.println(value);
Object value2 = Ognl.getValue("{@java.lang.System@getProperty(\"java.home\"),@java.lang.System@getProperty(\"java.runtime.name\")}", null);
System.out.println(value2);
}
/**
* 基于上下文的对象执行多个获取表达式,并将构成集合返回
* 这里其他是一个表达式, 构建集合(集合的每个元素分别对应一个表达式)
*/
@Test
public void multiGet() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
ognlContext.setRoot(buildOrder());
Object value = Ognl.getValue("{items[0].itemName,comment,orderNo.length(),1+1}", ognlContext, ognlContext.getRoot());
System.out.println(value);
}
/**
* 执行表达式列表:
* 1.上下文中的对象操作1
* 2.上下文中的对象操作2
* 3.上下文中的对象操作3
* 4.根据表达式上下文中解析
* 第4个表达式的返回值作为这个返回值
*/
@Test
public void multiInvoke() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
Order order = buildOrder();
ognlContext.setRoot(order);
Object value = Ognl.getValue("items.remove(0),address.setMobile(\"17511112222\"),tags.clear(),tags.size()", ognlContext, ognlContext.getRoot());
System.out.println(value);
}
3.11 位运算
@Test
public void base() throws OgnlException {
OgnlContext ognlContext = new OgnlContext();
System.out.println(Ognl.getValue("4 | 2", ognlContext,ognlContext.getRoot()));
System.out.println(Ognl.getValue("4 & 2", ognlContext,ognlContext.getRoot()));
System.out.println(Ognl.getValue("4 xor 2", ognlContext,ognlContext.getRoot()));
//左移 shipLeft
System.out.println(Ognl.getValue("8 << 1", ognlContext,ognlContext.getRoot()));
System.out.println(Ognl.getValue("8 shl 1", ognlContext,ognlContext.getRoot()));
//右边移 shipRight
System.out.println(Ognl.getValue("8 >> 1", ognlContext,ognlContext.getRoot()));
System.out.println(Ognl.getValue("8 shr 1", ognlContext,ognlContext.getRoot()));
//无条件右移 unlimited shipRight
System.out.println(Ognl.getValue("8 >>> 1", ognlContext,ognlContext.getRoot()));
System.out.println(Ognl.getValue("8 ushr 1", ognlContext,ognlContext.getRoot()));
}