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

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

@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()));
	}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【c 语言 】位操作符详解

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;C语言 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步&…

【机器学习300问】33、决策树是如何进行特征选择的?

还记得我在【机器学习300问】的第28问里谈到的&#xff0c;看决策树的定义不就是if-else语句吗怎么被称为机器学习模型&#xff1f;其中最重要的两点就是决策树算法要能够自己回答下面两问题&#xff1a; 该选哪些特征 特征选择该选哪个阈值 阈值确定 今天这篇文章承接上文&…

1137. 第N个泰波那契数- 力扣

1. 题目 泰波那契序列 Tn 定义如下&#xff1a; T0 0, T1 1, T2 1, 且在 n > 0 的条件下 Tn3 Tn Tn1 Tn2 给你整数 n&#xff0c;请返回第 n 个泰波那契数 Tn 的值。 2. 示例 3. 分析 1. 状态表示&#xff1a;dp[i]表示&#xff1a;第i个泰波那契数的值 2. 状态转移…

python疑难杂症(10)---Python函数def的定义分类,包括内置函数、外置函数、匿名函数、闭包函数、生成器函数等

本部分详细讲解Python函数的定义、常见的函数类型&#xff0c;尤其是特色函数包括内置函数、外置函数、匿名函数、闭包函数、生成器函数等以及用法。后续将对这类函数重点讲解使用方法。 函数定义&#xff1a; 函数是大多数编程语言使用的一个概念&#xff0c;函数是一段具有…

下载BenchmarkSQL并使用BenchmarkSQL查看OceanBase 的执行计划

下载BenchmarkSQL并使用BenchmarkSQL查看OceanBase 的执行计划 一、什么是BenchmarkSQL二、下载BenchmarkSQL三、使用BenchmarkSQL查看OceanBase 的执行计划 一、什么是BenchmarkSQL BenchmarkSQL是一个开源的数据库基准测试工具&#xff0c;可以用来评估数据库系统的性能&…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的草莓成熟度检测系统详解(深度学习模型+UI界面+Python代码+训练数据集)

摘要&#xff1a;本研究介绍了一个使用深度学习技术对草莓成熟度进行检测的系统&#xff0c;它采用了最新的YOLOv8算法&#xff0c;以及YOLOv7、YOLOv6、YOLOv5等前版本的算法&#xff0c;并对它们进行了性能对比。该系统能够在不同媒介上——如图像、视频文件、实时视频流和批…

28 批量归一化【李沐动手学深度学习v2课程笔记】(备注:这一节讲的很迷惑,很乱)

目录 1.批量归一化 1.1训练神经网络时出现的挑战 1.2核心思想 1.3原理 2.批量规范化层 2.1 全连接层 2.2 卷积层 2.3 总结 3. 代码实现 4. 使用批量规范化层的LeNet 5. 简明实现 1.批量归一化 现在主流的卷积神经网络几乎都使用了批量归一化 批量归一化是一种流行且…

Scrapy 爬虫框架

网络爬虫框架scrapy &#xff08;配置型爬虫&#xff09; 什么是爬虫框架&#xff1f; 爬虫框架是实现爬虫功能的一个软件结构和功能组件集合爬虫框架是个半成品&#xff0c;帮助用户实现专业网络爬虫 scrapy框架结构("52"结构) spider: 解析downloader返回的响…

【读论文】【精读】3D Gaussian Splatting for Real-Time Radiance Field Rendering

文章目录 1. What&#xff1a;2. Why&#xff1a;3. How&#xff1a;3.1 Real-time rendering3.2 Adaptive Control of Gaussians3.3 Differentiable 3D Gaussian splatting 4. Self-thoughts 1. What&#xff1a; What kind of thing is this article going to do (from the a…

传输层协议介绍(tcp,udp),可靠性和不可靠性

目录 传输层协议 介绍 tcp协议 介绍 面向连接 可靠性 面向字节流 udp协议 介绍 无连接 不可靠 面向数据报 可靠和不可靠 可靠 不可靠 传输层协议 介绍 传输层是计算机网络体系结构中的第四层&#xff0c;它负责在网络中的不同主机之间提供端到端的数据传输 传输…

ARMv8架构特殊寄存器介绍-1

1&#xff0c;ELR寄存器&#xff08;Exception Link Register &#xff09; The Exception Link Register holds the exception return address。 异常链接寄存器保存异常返回地址。最常用也很重要。 2&#xff0c;SPSR&#xff08;Saved Process Status Register&#xff09;…

PDF 文件与其他文档格式相比有哪些优势?

PDF文件与其他文档格式相比&#xff0c;具有许多明显的优势。首先&#xff0c;PDF是一种跨平台的文档格式&#xff0c;这意味着无论在哪种操作系统或设备上&#xff0c;用户都可以打开和查看PDF文件&#xff0c;而无需担心格式不兼容的问题。这种跨平台性使得PDF文件在办公、学…

Centos7安装postgresql14步骤

1、进入网址 https://www.postgresql.org/download/ 2、按步骤执行 # Install the repository RPM: sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm# Install PostgreSQL: sudo yum install -y…

基于springboot+vue的线上教育系统(源码+论文)

目录 前言 一、功能设计 二、功能实现 三、库表设计 四、论文 前言 现在大家的生活方式正在被计算机的发展慢慢改变着&#xff0c;学习方式也逐渐由书本走向荧幕,我认为这并不是不能避免的,但说实话,现在的生活方式与以往相比有太大的改变&#xff0c;人们的娱乐方式不仅仅…

PHP立体安全攻击向量:保护应用程序的关键挑战

PHP立体安全攻击向量&#xff1a;保护应用程序的关键挑战 PHP作为一种广泛使用的服务器端脚本语言&#xff0c;拥有庞大的用户群体和丰富的生态系统。然而&#xff0c;随着互联网的发展&#xff0c;网络安全问题也变得愈发严重。本文将深入探讨PHP的立体安全攻击向量&#xff0…

FPGA高端项目:FPGA基于GS2971+GS2972架构的SDI视频收发+图像缩放,提供3套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案的SDI接收发送本方案的SDI接收纯verilog图像缩放纯verilog多路视频拼接应用本方案的SDI接收HLS图像缩放HLS多路视频拼接应用本方案的SDI接收OSD动态字符叠加输出应用本方案的SDI接收HLS多路视频融合叠加应…

jupyter 修改文件保存位置 步骤

一、找到配置文件位置 打开Anaconda Prompt&#xff0c;输入&#xff1a; jupyter notebook --generate-config 根据得到的路径&#xff0c;以记事本方式打开配置文件 二、修改路径 在文件中输入&#xff1a; c.NotebookApp.notebook_dir E:\\deepLearning\\Jupyter_files…

SQL-2

• What have we achieved so far using SELECT ? — Retrieve data from all the rows and columns (whole table) — Retrieve data from all the rows and select columns — Retrieve data from select rows and columns • Sometimes we want to re-format the output fr…

​扩散模型(Diffusion Model)详解:直观理解、数学原理、PyTorch 实现​

在过去的大半年里&#xff0c;以Stable Diffusion为代表的AI绘画是世界上最为火热的AI方向之一。或许大家会有疑问&#xff0c;Stable Diffusion里的这个"Diffusion"是什么意思&#xff1f;其实&#xff0c;扩散模型(Diffusion Model)正是Stable Diffusion中负责生成…

【Preprocessing数据预处理】之Scaler

在机器学习中&#xff0c;特征缩放是训练模型前数据预处理阶段的一个关键步骤。不同的缩放器被用来规范化或标准化特征。这里简要概述了您提到的几种缩放器&#xff1a; StandardScaler StandardScaler 通过去除均值并缩放至单位方差来标准化特征。这种缩放器假设特征分布是正…