Spring(23)——SPEL表达式(二)-阿里云开发者社区

开发者社区> elim1> 正文

Spring(23)——SPEL表达式(二)

简介: 23.2.9 构造List 在SpEl中可以使用“{e1,e2,e3}”的形式来构造一个List,如下示例中我们就构造了一个List。 @Test public void test09() { ExpressionParser parser = new SpelExpressionParser(); List intList = (List)parser.
+关注继续查看

23.2.9 构造List

在SpEl中可以使用“{e1,e2,e3}”的形式来构造一个List,如下示例中我们就构造了一个List。

@Test
public void test09() {
	ExpressionParser parser = new SpelExpressionParser();
	List<Integer> intList = (List<Integer>)parser.parseExpression("{1,2,3,4,5,6}").getValue();
	int index = 0;
	for (Integer i : intList) {
		Assert.assertTrue(i == ++index);
	}
}

如果我们希望构造的List的元素还是一个List,则可以将构造的List的元素定义为“{e1,e2,e3}”这样的形式,如“{{1,2},{3,4,5},{6,7,8,9}}”。

@Test
public void test09_1() {
	ExpressionParser parser = new SpelExpressionParser();
	List<List<Integer>> list = (List<List<Integer>>)parser.parseExpression("{{1,2},{3,4,5},{6,7,8,9}}").getValue();
	int index = 0;
	for (List<Integer> intList : list) {
		for (Integer i : intList) {
			Assert.assertTrue(i == ++index);
		}
	}
}

如果需要构造一个空的List,则直接将对应的表达式字符串定义为“{}”即可。

23.2.10 构造Map

我们知道Map是可以key-value的形式存在的,在SpEl中如果我们需要构造一个Map则可以使用“{key1:value1,key2:value2}”这样的形式进行定义,即使用大括号包起来,然后key和value之间以冒号“:”分隔构成一个Entry,多个Entry之间以逗号分隔。如下示例中我们就构建了一个key为String,value为Long类型的Map。

@Test
public void test10() {
	ExpressionParser parser = new SpelExpressionParser();
	Map<String, Long> map = (Map<String, Long>)parser.parseExpression("{'key1':1L,'key2':2L}").getValue();
	Assert.assertTrue(map.get("key1").equals(1L));
	Assert.assertTrue(map.get("key2").equals(2L));
}

如果需要构造一个空的Map,则只需指定对应的表达式为“{:}”即可。

@Test
public void test10_1() {
	ExpressionParser parser = new SpelExpressionParser();
	Map<String, Long> map = (Map<String, Long>)parser.parseExpression("{:}").getValue();
	Assert.assertTrue(map.isEmpty());
}

23.2.11 构造数组

对于数组的构造就比较简单了,我们可以在表达式中使用Java代码中new的语法来构造一个数组。

@Test
public void test11() {
	ExpressionParser parser = new SpelExpressionParser();
	int[] nums = (int[])parser.parseExpression("new int[]{1,2,3}").getValue();
	Assert.assertTrue(nums.length==3);
}

如果需要构造一个空数组,则可以直接new一个空的数组。多维数组也是支持的,但是多维数组只支持定义一个空的数组,对于需要初始化指定数组元素的定义暂时在SpEl中是不支持的。

@Test
public void test11_1() {
	ExpressionParser parser = new SpelExpressionParser();
	int[][] nums = (int[][])parser.parseExpression("new int[2][3]").getValue();//正确
	int[][] nums2 = (int[][])parser.parseExpression("new int[2][3]{{1,2,3},{4,5,6}}").getValue();//错误
}

23.2.12 集合选择

SpEl允许我们将集合中的某些元素选出组成一个新的集合进行返回,这就是所谓的集合。打个比方,我们有一个List,其包含1-9共9个数字,通过集合选择的功能我们可以选出其中的奇数组成一个新的List进行返回,即1、3、5、7、9。集合的选择使用的语法是“collection.?[condition]”,condition中直接使用的属性、方法等都是针对于集合中的元素来的。如下示例中我们的user对象的getInterests()方法返回包含三个元素的List,然后我们通过endsWith(‘Ball’)筛选出以Ball结尾的元素组成一个新的List。

@Test
public void test12_1() {
	Object user = new Object() {
		public List<String> getInterests() {
			List<String> interests = new ArrayList<String>();
			interests.add("BasketBall");
			interests.add("FootBall");
			interests.add("Movie");
			return interests;
		}
	};
	ExpressionParser parser = new SpelExpressionParser();
	List<String> interests = (List<String>)parser.parseExpression("interests.?[endsWith('Ball')]").getValue(user);
	Assert.assertTrue(interests.size() == 2);
	Assert.assertTrue(interests.get(0).equals("BasketBall"));
	Assert.assertTrue(interests.get(1).equals("FootBall"));
}

对于Map的选择而言,其中的condition中直接使用的属性和方法针对的主体都是Map的Entry。如下示例中我们通过条件value.endsWith(‘Ball’)选出Map中value以Ball结尾的Entry组成一个新的Map进行返回,对应的条件相当于Entry.getValue().endsWith(“Ball”)。

@Test
public void test12_2() {
	Object user = new Object() {
		public Map<String, String> getInterests() {
			Map<String, String> interests = new HashMap<String, String>();
			interests.put("key1", "BasketBall");
			interests.put("key2", "FootBall");
			interests.put("key3", "Movie");
			return interests;
		}
	};
	ExpressionParser parser = new SpelExpressionParser();
	Map<String, String> interests = (Map<String, String>)parser.parseExpression("interests.?[value.endsWith('Ball')]").getValue(user);
	Assert.assertTrue(interests.size() == 2);
	Assert.assertTrue(interests.get("key1").equals("BasketBall"));
	Assert.assertTrue(interests.get("key2").equals("FootBall"));
}

23.2.13 集合投影

集合投影的意思是将集合中每个元素的某部分内容的组成一个新的集合进行返回。集合投影的语法是“collection.![projectionExpression]”,其中projectionExpression中直接使用的属性和方法都是针对于collection中的每个元素而言的,对于List而言其就表示List中的每个元素,对于Map而言,其就表示Map中的每个Entry。在如下示例中我们就将List中的每一个元素调用endsWith()方法后的结果组成一个新的List进行返回。

@Test
public void test13_1() {
	Object user = new Object() {
		public List<String> getInterests() {
			List<String> interests = new ArrayList<String>();
			interests.add("BasketBall");
			interests.add("FootBall");
			interests.add("Movie");
			return interests;
		}
	};
	ExpressionParser parser = new SpelExpressionParser();
	List<Boolean> interests = (List<Boolean>)parser.parseExpression("interests.![endsWith('Ball')]").getValue(user);
	Assert.assertTrue(interests.size() == 3);
	Assert.assertTrue(interests.get(0).equals(true));
	Assert.assertTrue(interests.get(1).equals(true));
	Assert.assertTrue(interests.get(2).equals(false));
}

Map进行投影的结果是一个List。如下示例中我们就将一个Map的value投影为一个List,对应List中元素的顺序是不定的。

@Test
public void test13_2() {
	Object user = new Object() {
		public Map<String, String> getInterests() {
			Map<String, String> interests = new HashMap<String, String>();
			interests.put("key1", "BasketBall");
			interests.put("key2", "FootBall");
			interests.put("key3", "Movie");
			return interests;
		}
	};
	ExpressionParser parser = new SpelExpressionParser();
	List<String> interests = (List<String>)parser.parseExpression("interests.![value]").getValue(user);
	Assert.assertTrue(interests.size() == 3);
	for (String interest : interests) {
		Assert.assertTrue(interest.equals("BasketBall") || interest.equals("FootBall") || interest.equals("Movie"));
	}
}

23.2.14 设置变量

在前面我们已经介绍了EvaluationContext和rootObject的用法,貌似使用EvaluationContext时直接使用rootObject更简单一些。那是不是所有使用EvaluationContext的地方都可以改成使用rootObject呢?答案是否定的。EvaluationContext的功能相比rootObject而言还是要丰富很多的,如其可以设置变量、方法等供表达式使用。对于变量而言,我们可以通过EvaluationContext的setVariable()方法进行设置,然后在表达式中使用时通过“#varName”的形式进行使用。如下示例中我们就给EvaluationContext设置了一个名为“user”的变量,然后在表达式中通过“#user”来使用该变量。

@Test
public void test14() {
	Object user = new Object() {
		public String getName() {
			return "abc";
		}
	};
	EvaluationContext context = new StandardEvaluationContext();
	//1、设置变量
	context.setVariable("user", user);
	ExpressionParser parser = new SpelExpressionParser();
	//2、表达式中以#varName的形式使用变量
	Expression expression = parser.parseExpression("#user.name");
	//3、在获取表达式对应的值时传入包含对应变量定义的EvaluationContext
	String userName = expression.getValue(context, String.class);
	//表达式中使用变量,并在获取值时传递包含对应变量定义的EvaluationContext。
	Assert.assertTrue(userName.equals("abc"));
}

#root

#root在表达式中永远都指向对应EvaluationContext的rootObject对象。在如下示例中#root就指向了对应的user对象。

@Test
public void test14_1() {
	Object user = new Object() {
		public String getName() {
			return "abc";
		}
	};
	EvaluationContext context = new StandardEvaluationContext(user);
	ExpressionParser parser = new SpelExpressionParser();
	Assert.assertTrue(parser.parseExpression("#root.name").getValue(context).equals("abc"));
}

#this

#this永远指向当前对象,其通常用于集合类型,表示集合中的一个元素。如下示例中我们就使用了#this表示当前元素以选出奇数作为一个新的List进行返回。

@Test
public void test14_2() {
	ExpressionParser parser = new SpelExpressionParser();
	List<Integer> intList = (List<Integer>)parser.parseExpression("{1,2,3,4,5,6}").getValue();
	EvaluationContext context = new StandardEvaluationContext(intList);
	//从List中选出为奇数的元素作为一个List进行返回,1、3、5。
	List<Integer> oddList = (List<Integer>)parser.parseExpression("#root.?[#this%2==1]").getValue(context);
	for (Integer odd : oddList) {
		Assert.assertTrue(odd%2 == 1);
	}
}

23.2.15 注册方法

StandardEvaluationContext允许我们在其中注册方法,然后在表达式中使用对应的方法。注册的方法必须是一个static类型的公有方法。注册方法是通过StandardEvaluationContext的registerFunction(funName,method)方法进行,其中第一个参数表示需要在表达式中使用的方法名称,第二个参数表示需要注册的java.lang.reflect.Method。在表达式中我们可以使用类似于“#funName(params…)”的形式来使用对应的方法。如下示例中我们就通过StandardEvaluationContext注册了一个名叫plusTen的方法。

	static class MathUtils {
		public static int plusTen(int i) {
			return i+10;
		}
	}
	
	@Test
	public void test15() throws NoSuchMethodException, SecurityException {
		ExpressionParser parser = new SpelExpressionParser();
		//1、获取需要设置的java.lang.reflect.Method,需是static类型
		Method plusTen = MathUtils.class.getDeclaredMethod("plusTen", int.class);
		StandardEvaluationContext context = new StandardEvaluationContext();
		//2、注册方法到StandardEvaluationContext,第一个参数对应表达式中需要使用的方法名
		context.registerFunction("plusTen", plusTen);
		//3、表达式中使用注册的方法
		Expression expression = parser.parseExpression("#plusTen(10)");
		//4、传递包含对应方法注册的StandardEvaluationContext给Expression以获取对应的值
		int result = expression.getValue(context, int.class);
		Assert.assertTrue(result == 20);
	}

 

 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
使用spring@Schedule注解定时任务时将时间表达式写入配置文件中的方法
@PropertySource("classpath:root/test.props") 然后修改你的@Scheduled(cron="0/5 * * * * ? ") 为 @Scheduled(cron="${jobs.
1925 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
3958 0
Spring Boot 2.4 新特性,全新的Cron表达式处理机制
为什么要替代原有的 CronSequenceGenerator ? 此处理器是基于 `java.util.Calendar`局限性比较大,无法完成`last day of month` 语义。
149 0
JSP第四篇【EL表达式介绍、获取各类数据、11个内置对象、执行运算、回显数据、自定义函数、fn方法库】
什么是EL表达式? 表达式语言(Expression Language,EL),EL表达式是用"${}"括起来的脚本,用来更方便的读取对象! EL表达式主要用来读取数据,进行内容的显示! 为什么要使用EL表达式? 为什么要使用EL表达式,我们先来看一下没有EL表达式是怎么样读取对象数据的吧! 在1.
1124 0
Web---JSP-EL表达式
EL表达式简介 EL 全名为Expression Language。 EL主要作用: 获取数据: EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的java对象中获取数据。
743 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
10714 0
阿里云服务器远程登录用户名和密码的查询方法
阿里云服务器远程连接登录用户名和密码在哪查看?阿里云服务器默认密码是什么?云服务器系统不同默认用户名不同
81 0
spring框架的定时任务cronExpression表达式详解
附:cronExpression表达式解释: 0 0 12 * * ?---------------在每天中午12:00触发 0 15 10 ? * *---------------每天上午10:15 触发 0 15 1...
1309 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
2901 0
+关注
elim1
喜欢研究技术的码农
258
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载