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使用总结 - 源链接在此 >>

一、简介

OGNL(Object-Graph Navigation Language的简称),对象图导航语言,通过表达式来实现:

许多常用框架都集成了ognl,如mybatis、struts、spring、arthas等。

本文详细总结了Ognl的大部分使用场景,阅读前请收藏。 这里仅以java环境下的代码进行演示。

二、快速入门

  • 引入依赖
<dependency><groupId>ognl</groupId><artifactId>ognl</artifactId><version>3.0.19</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类型的对象,可以放根对象和普通对象。

img

三、详细使用

创建测试实体

@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.1 基本数据类型

一般都是用来判断相等、比较(比较参考后面的逻辑运算)

@Testpublic 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);}@Testpublic 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 对象类型

/*** 创建对象*/@Testpublic 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));}/*** 获取简单属性*/@Testpublic void getAttr() throws OgnlException {Order order = buildOrder();String comment = (String) Ognl.getValue("comment", order);System.out.println("comment:"+comment);}/*** 获取嵌套属性*/@Testpublic void getNestedAttr() throws OgnlException {Order order = buildOrder();String mobile = (String) Ognl.getValue("address.mobile", order);System.out.println("mobile:"+mobile);}/*** 调用属性的方法,不能省略方法的括号,有参方法也可以调用*/@Testpublic 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);}/*** 设置属性*/@Testpublic void setAttr() throws OgnlException {Order order = buildOrder();Ognl.setValue("comment", order,"不要加香菜啊");System.out.println("after setValue:"+ order.getComment());}/*** 获取class*/@Testpublic 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

/*** 基于常量构建*/@Testpublic 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));}/*** 构建的元素可以基于方法调用或现有上下文构建*/@Testpublic 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的表达式*/@Testpublic 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的表达式*/@Testpublic 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的表达式*/@Testpublic 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的表达式*/@Testpublic 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));}/*** 获取元素*/@Testpublic 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的方法*/@Testpublic 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());}/*** 替换元素*/@Testpublic 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集合

/*** 构建*/@Testpublic 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的表达式*/@Testpublic 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的表达式*/@Testpublic 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的表达式*/@Testpublic 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的表达式*/@Testpublic 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));}/*** 常调用的方法*/@Testpublic 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集合

/*** 构建*/@Testpublic 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)方法*/@Testpublic 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的方法*/@Testpublic 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 数组

/*** 构建*/@Testpublic 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格式反序列化创建}/*** 获取元素*/@Testpublic void getByIndex() throws OgnlException {Order order = buildOrder();Object promotionTypes2 = Ognl.getValue("promotionTypes[1]", order);System.out.println("promotionTypes2:"+ promotionTypes2);}/*** 获取length*/@Testpublic 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方法(参数简化为基本类型)*/@Testpublic 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必须为全路径*/@Testpublic 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 算术运算

/*** 表达式中可以直接运用加减乘除等*/@Testpublic 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 逻辑运算

/*** 条件*/@Testpublic 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);}@Testpublic 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);}/*** 内部表达式用括号括起来*/@Testpublic 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()));}@Testpublic 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);}/*** 判断元素是否在集合或数组当中,一般用户基本元素*/@Testpublic 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()));}@Testpublic 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*/@Testpublic 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);}/*** 基于上下文的对象执行多个获取表达式,并将构成集合返回* 这里其他是一个表达式, 构建集合(集合的每个元素分别对应一个表达式)*/@Testpublic 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个表达式的返回值作为这个返回值*/@Testpublic 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 位运算

@Testpublic 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()));//左移 shipLeftSystem.out.println(Ognl.getValue("8 << 1", ognlContext,ognlContext.getRoot()));System.out.println(Ognl.getValue("8 shl 1", ognlContext,ognlContext.getRoot()));//右边移 shipRightSystem.out.println(Ognl.getValue("8 >> 1", ognlContext,ognlContext.getRoot()));System.out.println(Ognl.getValue("8 shr 1", ognlContext,ognlContext.getRoot()));//无条件右移 unlimited shipRightSystem.out.println(Ognl.getValue("8 >>> 1", ognlContext,ognlContext.getRoot()));System.out.println(Ognl.getValue("8 ushr 1", ognlContext,ognlContext.getRoot()));}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/740207.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python3:No module named ‘pandas‘

一、背景 电脑里下载了python3&#xff0c;vscode使用的是python 书接上条博文&#xff0c;在我设置了vscode的默认地址后&#xff0c;下载pandas运行还是找不到 这里看到我已经成功的安装了pandas-2.2.1 二、发现问题 在设置vscode默认的python环境中寻找pandas&#xff08;…

Android Gradle 开发与应用 (六) : 创建buildSrc插件和使用命令行创建Gradle插件

1. 前言 前文中&#xff0c;我们介绍了在Android中&#xff0c;如何基于Gradle 8.2&#xff0c;创建Gradle插件。这篇文章&#xff0c;我们以buildSrc的方式来创建Gradle插件。此外&#xff0c;还介绍一种用Cmd命令行的方式&#xff0c;来创建独立的Gradle插件的方式。 1.1 本…

idea:忽略不要搜索unpackage文件夹

开发vue时搜索关键字&#xff0c;会搜索到编译后的文件&#xff0c;如unpackage。&#xff08;注意这个是idea工具&#xff0c;和Git忽略是有区别的&#xff09; File->Settings->Editor->File Types

c 语言中指针注意事项

看看下面两个 #include<iostream> using namespace std;int main() {int a 10;char p[6];*((int *)p) *(& a); // 正确写法*p *(&a); // 错误写法cout << *(int*)p; } 把原因写在评论区

由于 Positive Technologies 的专业知识,Moxa 消除了工业无线转换器中的一个漏洞。

我们的专家在 NPort W2150A 和 W2250A 转换器中发现了该漏洞 - 这些设备可将工业控制器、仪表和传感器连接到本地 Wi-Fi 网络。Moxa 已根据负责任的披露政策通知了该威胁&#xff0c;并发布了软件更新。 &#x1f977; 攻击者可以完全访问这些设备。 Positive Technologies 公…

【FAQ】推送获取push token报错6003,如何排查?

一、问题现象 客户端调用getToken方法获取push token失败并报错&#xff0c;关键错误日志&#xff1a;com.huawei.hms.common. ApiException: 6003: certificate fingerprint error。 二、问题排查 6003错误码在“常见错误码”说明文档中有说明&#xff1a; 检查申请相关服务…

JSONObject在Android Main方法中无法实例化问题

目录 前言一、Main(非安卓环境)方法下运行二、安卓坏境下运行三、why? 前言 原生的json,即org.json.JSONObject; 在Android Studio中的Main方法里运行报错&#xff0c;但在安卓程序运行过程正常 一、Main(非安卓环境)方法下运行 static void test() {try {// 创建一个 JSON …

_locate_stream(Workbook): seen 报错处理

找到compdoc.py文件 注释428和429行 加pass 处理前报错如下&#xff1a; 处理后 无报错打印

HTTPS网络请求失败WiFi请求成功

在xml的config文件中添加raw文件位置 raw文件是证书的pem文件去掉key文件 文件名称去掉多余的.cn

【C语言】初步解决指针疑惑

✨✨ 欢迎大家来到莉莉的博文✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 目录 一.理解内存和编址 1.1理解内存 1.2理解编址 二.指针变量和地址 1.1取地址操作符 三.指针变量和解引用操作符&#xff08;*&#xff09; …

大模型时代下的 BI——智能问数

「智能问数」是 Sugar BI 基于文心大语言模型推出的对话式数据问答产品&#xff0c;让用户能够通过自然语言的方式进行对答形式的数据查询&#xff0c;系统自动使用可视化图表的方式呈现数据结果&#xff0c;并支持对数据做summary总结。 智能问数功能邀测中&#xff0c;欢迎CS…

音视频开发_视频基础知识

RGB彩色原理 RGB 是表示红色 (Red)、绿色 (Green) 和蓝色 (Blue) 三种颜色的色彩模式&#xff0c;这是一种加色法。在 RGB 色彩模式中&#xff0c;通过不同比例的红、绿、蓝三原色的混合可以得到各种不同颜色。这是因为人眼对红、绿、蓝三种颜色特别敏感&#xff0c;通过它们的…

Mybatis sql 控制台格式化

package com.mysql; import org.apache.commons.lang.StringUtils; import org.apache.ibatis.logging.Log;import java.util.*;/*** Description: sql 格式化* Author: DingQiMing* Date: 2023-07-17* Version: V1.0*/ public class StdOutImpl implements Log {private stati…

简述类与对象

一、两者关系 类是Java语言中最重要的数据类型&#xff0c;用于创建具体实例&#xff08;对象&#xff09; 抽象出一类事物共有的属性和行为&#xff0c;即数据以及数据上的操作 类是对现实事物的模拟&#xff0c;包含属性&#xff08;成员变量&#xff09;和行为&#xff0…

Vue3全家桶 - Vue3 - 【1】前置准备和介绍(VsCode插件 + 组合式API和选项式API的比较)

一、前言 Vue2.7是当前、同时也是最后一个 Vue2.x 的次级版本更新。Vue2.7 会以其发布日期&#xff0c;即2022年7月1日开始计算&#xff0c;提供18个月的长期技术支持。在此期间&#xff0c;Vue2将会提供必要的bug修复和安全修复。但不再提供新特性。Vue2的终止支持时间是2023…

【C语言步行梯】自定义函数、函数递归详谈

&#x1f3af;每日努力一点点&#xff0c;技术进步看得见 &#x1f3e0;专栏介绍&#xff1a;【C语言步行梯】专栏用于介绍C语言相关内容&#xff0c;每篇文章将通过图片代码片段网络相关题目的方式编写&#xff0c;欢迎订阅~~ 文章目录 什么是函数库函数自定义函数函数执行示例…

Python docx学习笔记

个人学习笔记。 1 工具介绍 python-docx 是用于创建可修改 微软 Word 的一个 python 库&#xff0c;提供全套的 Word 操作&#xff0c;是最常用的 Word 工具。 1.1 基本概念 Document&#xff1a;是一个 Word 文档 对象&#xff0c;不同于 VBA 中 Worksheet 的概念&#xf…

李彦宏最新发声,“程序员”职业将不复存在!

文章目录 “程序员”职业不存在周鸿祎的看法我怎么看 昨天&#xff0c;百度一则新闻冲上了微博和知乎热搜。 “程序员”职业不存在 关于李彦宏的这个观点&#xff0c;瞬间激起热烈讨论。有赞同的、有直接开喷的&#xff0c;也有看热闹不嫌事大的。还有网友将这个问题抛给你百度…

嵌入式系统工程师错题总结

笔者来介绍一下嵌入式系统工程师考试的一些易错题目 题目介绍  流水线指令计算公式&#xff1a;一条指令总时间max&#xff08;单个指令执行时间&#xff09;*&#xff08;指令数-1&#xff09;  平均故障间隔时间  ICMP协议&#xff1a;传送通信问题相关的消息。 …

【网络】数据在同网段和跨网段通信流程

情景一&#xff1a;同一广播域内&#xff0c;两台主机通信过程&#xff1a; 当NO要和N1通信时&#xff0c;假如N0知道N1的IP但却不知道它的MAC地址&#xff0c;那NO就会发送一个ARP的广播请求<1>&#xff08;里面源IP是NO 目标IP是N1 源MAC是N0 目标MAC是12个F&#xff0…