Ognl使用总结

news2024/11/17 5:21:16

目录

  • 一、简介
  • 二、快速入门
  • 三、详细使用
    • 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的简称),对象图导航语言,通过表达式来实现:

  1. 设置/获取Java对象及属性
  2. 集合操作
  3. 对象方法调用
  4. 静态方法调用
  5. 表达式串联

许多常用框架都集成了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()));
	}

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

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

相关文章

开始使用chat-gpt4

目录 一、说明 二、安装步骤 三、测试效果咋样 &#xff08;1&#xff09;写代码能力 &#xff08;2&#xff09;回答问题能力 &#xff08;3&#xff09;写作能力 一、说明 参考&#xff08;非常感谢这位博主的分享&#xff09;&#xff1a;http://t.csdn.cn/qypw9 注意&…

FTP服务器项目

文章目录 1. 项目简介2. FTP协议和用到指令说明2.1 FTP协议详解2.2 指令说明 3. FTP项目的类图分析3.1 UML3.2 工厂类XFtpFactoryXFtpFactory.hXFtpFactory.cpp 2.2 XFtpTaskXFtpTask.hXFtpTask.cpp 2.3 XFtpServerCMDXFtpServerCMD.hXFtpServerCMD.cpp 4. 运行演示FileZilla的…

数字逻辑期末必刷卷(基础卷)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 &#x1f4a1;一、填空题&#xff08;每空1分&#xff0c;共20分&#xff09;&#x1f4a1;二、单项选择题&#xff08;每小题2分&#xff0c;共20分&#xff09;&a…

第七章 Linux实际操作——组管理和权限管理

第七章 Linux实际操作——组管理和权限管理 7.1 Linux组基本介绍7.2 文件、目录 所有者7.2.1 查看文件的所有者7.2.2 修改文件所有者 7.3 组的创建7.3.1 基本指令7.3.2 应用实例 7.4 文件、目录所在组7.4.1 查看文件、目录所在组7.4.2 修改文件、目录所在组 7.5 其他组7.6 权限…

观澜南林輋旧改回迁房--周边巨量旧改,未来区政府核心商圈。

项目亮点 观澜福城街道办旧改最集中的区域&#xff0c;且地铁4号的茜坑站就在门口&#xff01;未来一区域成为龙华区政府的中心地段。本项目拆迁约10万&#xff0c;主打高端商业综合体&#xff0c;项目规划27班九年一贯性学校&#xff0c;约4万多平用于建设公共设施、绿地。 …

ROS学习——通信机制(服务通信)

2.2.3 服务通信自定义srv调用A(C) Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 068服务通信(C)3_客户端优化_Chapter2-ROS通信机制_哔哩哔哩_bilibili 一、理论模型 服务通信也是ROS中一种极其常用的通信模式&#xff0c;服务通信是基于请求响应模式的&#xf…

【Java|多线程与高并发】volatile关键字和内存可见性问题

文章目录 1.前言2. 编译器优化带来的内存可见性问题3. 使用volatile保证内存可见性5.volatile不能保证原子性以JMM的角度看待volatile总结 1.前言 synchronized和volatile都是Java多线程中很重要的关键字&#xff0c;但它们的作用和使用场景有所不同。 synchronized关键字可以…

Linux之文件打包和解压缩

任务描述 有时&#xff0c;我们会在Linux系统中将多个文件打包成一个单独的文件&#xff0c;通过本关的学习&#xff0c;我们将学会如何在Linux系统中将多个文件/目录打包生成一个文件。 本关任务&#xff1a;使用tar命令完成文件和目录的打包操作。 相关知识 tar&#xff…

验证断言(立即断言并行断言)

目录 1.何为断言 2.断言的作用&#xff1a; 3.断言的种类 3.1立即断言 3.2并发断言 4.断言层次结构 4.1 sequence 序列 4.2 property 序列 5.sequence和property的异同 6.补充知识点&#xff08;assert/cover/assume&#xff09; 7.写在后边 1.何为断言 断言主要…

网络知识点之-FTP协议

FTP协议指文件传输协议&#xff08;File Transfer Protocol&#xff0c;FTP&#xff09;&#xff0c;是用于在网络上进行文件传输的一套标准协议&#xff0c;它工作在 OSI 模型的第七层&#xff0c; TCP 模型的第四层&#xff0c; 即应用层&#xff0c; 使用 TCP 传输而不是 UD…

第一节 初识C语言

第一节 初识C语言 目录 一&#xff0e; 什么是C语言二&#xff0e; 第一个C语言程序三&#xff0e; 数据类型四&#xff0e; 变量与常量五&#xff0e; 未完待续 本章重点&#xff1a; 什么是C语言第一个C语言程序数据类型变量、常量字符串转义字符注释选择语句循环语句函数数组…

【LeetCode】每日一题 -- 1171. 从链表中删去总和值为零的连续节点 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/remove-zero-sum-consecutive-nodes-from-linked-list/ 1. 题解&#xff08;1171. 从链表中删去总和值为零的连续节点&#xff09; 2021年字节二面真题 1.1 暴力解法&#xff1a;穷举 时间复杂度 O(n2)&#xff0c;空间复杂…

Python系列之面向对象编程

目录 一、面向对象编程 1.1 面向对象三大特征 1.2 什么是对象 二、类(class)和实例(instance) 2.1 类的构成 2.2 创建类 2.3 创建实例对象和访问属性 2.4 Python内置类属性 2.5 类属性与方法 三、类的继承 3.1 方法重写 四、多态 一、面向对象编程 1.1 面向对象三大…

抖音短视频矩阵系统-源码-系统搭建

目录 1. 短视频AI智能创作 2. 托管式账号管理: 3. 数据分析 4. 智能营销获客 开发流程 抖音账号矩阵系统开发&#xff0c;抖音账号矩阵系统源码搭建&#xff0c;抖音账号技术系统源码部署 抖音矩阵系统专注于为短视频私域运营达人或企业提供一站式赋能服务平台。具体包括智…

小议CSDN周赛57期 - 凑数

本期周赛几乎忘记参加&#xff0c;在最后几分钟的时候上来看了看。那些选择判断一通乱选&#xff0c;填空题也已经被吐槽得差不多了&#xff0c;这里不多说&#xff0c;只说我对第一道编程题的看法&#xff08;吐槽&#xff09;。因为 C 站的机制是&#xff0c;即使它错了&…

彻底理解HTTPS加密原理

目录 1.为什么需要加密&#xff1f; 2.什么是对称加密&#xff1f; 3.什么是非对称加密&#xff1f; 4.非对称加密对称加密&#xff1f; 5.数字证书 6.数字签名 相信大家对于HTTP与HTTPS的区别都有了解&#xff0c;那么对于HTTPS的加密过程你是否知道呢&#xff1f; 对称…

单片机内存管理

单片机内存管理 1、随机存储器 RAM是随机存储器&#xff0c;读写速度快&#xff0c;但掉电以后数据会丢失。它分为SRAM(静态RAM)和DRAM(动态RAM)。SRAM无需刷新就可以保存数据&#xff1b;DRAM需要不断刷新才可以保存数据。在CPU内部的RAM&#xff0c;就叫内部RAM&#xff0c…

算法模板(3):搜索(4):高等图论

高等图论 有向图的强连通分量 相关概念 强连通分量&#xff1a;Strongly Connected Component (SCC).对于一个有向图顶点的子集 S S S&#xff0c;如果在 S S S 内任取两个顶点 u u u 和 v v v&#xff0c;都能找到一条 u u u 到 v v v 的路径&#xff0c;那么称 S S…

JVM零基础到高级实战之Java程序员不可不知的对象创建底层步骤细节

JVM零基础到高级实战之Java程序员不可不知的对象创建底层步骤细节 JVM零基础到高级实战之Java程序员不可不知的对象创建底层步骤细节 文章目录 JVM零基础到高级实战之Java程序员不可不知的对象创建底层步骤细节前言Java对象创建的流程步骤包括哪些&#xff1f;总结 前言 JVM零…

【云原生 | 53】Docker三剑客之Docker Compose应用案例一:Web负载均衡

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 &#x1f3c5;阿里云ACE认证高级工程师 &#x1f3c5;阿里云开发者社区专…