Spring3表达式语言(SpEL)学习笔记

时间:2023-03-09 08:22:49
Spring3表达式语言(SpEL)学习笔记

最新地址请访问:http://leeyee.github.io/blog/2011/06/19/spring-expression-language

Spring Excpression Language (SpEL)语言支持在运行时操作和查询对象,其语法类似统一的EL语言,但是SpEL提供了额外的功能。

1、文本表达式

2、布尔类和关系操作

3、正则表达式

4、类表达式

5、访问属性、数组、集合和map

6、方法调用

7、关系操作

8、赋值操作

9、调用构造函数

10、Bean 引用

11、数组构造

12、内联list

13、三元操作

14、变量

15、用户自定义函数

16、集合投影

17、集合选择

18、模板表达式

使用SpEl进行表达式操作,基本操作如下:

第一步,构建解析

[java] view
plain
copy
  1. ExpressionParser parser = new SpelExpressionParser();

第二步,使用表达式进行解析

[java] view
plain
copy
  1. Expression exp = parser.parseExpression( SpEl);

第三步,获取结果

[java] view
plain
copy
  1. exp.getValue()

2.1 文本表达式

文本表达式支持字符表达式、日期、数字(正数、实数及十六进制数)、布尔类型及null.其中字符表达式需要用单引号声明。

对数字支持负数、指数及小数。默认情况下实数使用Double.parseDouble() 进行表达式类型转换

2.2 属性、数组、列表、字典(map)及索引

在表达式中访问类属性时直接使用属性名,属性名首字母大小写均可。

访问数组时可以使用[index]进行元素对象范围。

访问列表时,可直接使用类表的方法,通过点操作符

2.3 内置列表

列表可以直接表示在表达式中使用{}符号表达。{}本身代表一个空的list

2.4 数组构造(spring3.0.3中会抛出异常)

可以通过熟悉的java语法在表达是语言中定义。但目前不支持定义一个初始化的多维数组

2.5 方法

表达式中的方法调用遵循java语法。

2.6 操作符

2.6.1 关系操作符


支持 eq("=="),ne("!="),le("<="),lt("<"),gt(">"),ge(">="),div("/"),mod("%"),not("!"),正则表达式及instanceof操作              

2.6.2 逻辑操作符

逻辑操作符支持and,or,not

2.6.3 数学运算操作符

加法运算符可以用于数字,字符串和日期。减法可以用在数字和日期。乘法和除法只能用于对数字。其他受支持的数学运算是模数(%)和指数幂(^)。运行顺序按标准运算符优先级执行

2.7 赋值

通过赋值操作进行属性设置。通常是调用setValue方法,但也可以在调用getValue时设置。

2.8 类型

通过特殊的'T'操作符可以用来指定一个java.lang.Class的实例。在实例话对象的静态方法将会被调用。

2.9 构造器

构造器通过new操作被调用。在new操作时需要指明类的完全类名(包括包路径)

2.10 变量

变量可以通过 #变量名 在表达式中被引用。变量通过StandardEvaluationContext类的setVariable方法进行设置

2.10.1 #this变量

变量 #this 被定义为当前操作对象的引用。

2.11 函数

你可以扩展SpEL通过注册自定义函数。注册后的函数可以在表达式中通过其名称进行调用。函数的注册是通过StandardEvaluationContext类的registerFunction方法进行声明

2.12 三元操作

2.13 Elvis操作

Elvis操作是一个短的三元操作符语法,通常在Groovy语言中使用。

Note: Elvis操作在表达式中可以用来生成默认值,当被访问属性为空时。比如@Value

@Value("#systemPro['mail.port'] ? : 25}")  //当mail.port为空时将默认为25

2.14 安全导航操作

该操作是为避免空指针异常。他是来自Groovy语言的。典型的当你有一个指向对象的引用,在你访问其方法或属性时,可能需要验证该对象的方法或属性是否为空,为了避免验证,使用安全导航操作将简单的返回null而不是空指针异常。

2.15 集合选择

选择是一个强大的表达式语言属性,可以使用选择表达式过滤源集合,从而生成一个新的符合选择条件的集合

选择的语法为 ?[selectionExpression] 。他将过滤集合并且返回一个新的集合(原集合的子集)。

选择语句也可用在Map中,过滤keySet及valueSet分别使用key和value关键字

另外:选择语法中,选择符合条件的结果集的第一个元素的语法为 ^[selectionExpression],选择最后一个元素的语法为$[selectionExpression]

2.16 集合投影

语法 ![projectionExpression] 判断集合中每个元素是否符合语法要求

2.17 表达式模板

表达式模板允许混合文字表达式,一个或多个值计算块。每一个值计算块被声明通过可被自定义的前缀和后缀,一般选择使用 #{}作为一个定界符。

------------    以上就是SpEL的简单介绍。下面直接给出测试用例,这样比较直观,也易于理解。    ------------

pom.xml

[xhtml] view
plain
copy
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3. <modelVersion>4.0.0</modelVersion>
  4. <groupId>study.spring3</groupId>
  5. <artifactId>study-spring3</artifactId>
  6. <version>0.0.1-SNAPSHOT</version>
  7. <dependencies>
  8. <dependency>
  9. <groupId>org.springframework</groupId>
  10. <artifactId>spring-context</artifactId>
  11. <version>3.0.5.RELEASE</version>
  12. <scope>runtime</scope>
  13. <exclusions>
  14. <exclusion>
  15. <groupId>commons-logging</groupId>
  16. <artifactId>commons-logging</artifactId>
  17. </exclusion>
  18. </exclusions>
  19. </dependency>
  20. <dependency>
  21. <groupId>org.slf4j</groupId>
  22. <artifactId>slf4j-api</artifactId>
  23. <version>1.5.8</version>
  24. <scope>runtime</scope>
  25. </dependency>
  26. <dependency>
  27. <groupId>org.slf4j</groupId>
  28. <artifactId>slf4j-log4j12</artifactId>
  29. <version>1.5.8</version>
  30. <scope>runtime</scope>
  31. </dependency>
  32. <dependency>
  33. <groupId>log4j</groupId>
  34. <artifactId>log4j</artifactId>
  35. <version>1.2.14</version>
  36. <scope>runtime</scope>
  37. </dependency>
  38. <dependency>
  39. <groupId>junit</groupId>
  40. <artifactId>junit</artifactId>
  41. <version>4.8.1</version>
  42. <scope>test</scope>
  43. </dependency>
  44. <dependency>
  45. <groupId>commons-logging</groupId>
  46. <artifactId>commons-logging</artifactId>
  47. <version>1.1.1</version>
  48. <scope>test</scope>
  49. </dependency>
  50. <dependency>
  51. <groupId>javax.inject</groupId>
  52. <artifactId>javax.inject</artifactId>
  53. <version>1</version>
  54. <scope>runtime</scope>
  55. </dependency>
  56. <dependency>
  57. <groupId>cglib</groupId>
  58. <artifactId>cglib</artifactId>
  59. <version>2.1_3</version>
  60. <scope>runtime</scope>
  61. </dependency>
  62. </dependencies>
  63. </project>

spring-beans.xml

[xhtml] view
plain
copy
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  4. xmlns:p="http://www.springframework.org/schema/p"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  6. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
  7. <!-- 容器注解扫描 -->
  8. <context:component-scan base-package="study.spring.beans" />
  9. <bean id="sputil" name="sputil" class="study.spring.beans.SpElUtil">
  10. <property name="time" value="#{ new java.util.Date()}" />
  11. <property name="name" value="#{'override'}" />
  12. <property name="maps">
  13. <map>
  14. <entry key="1" value="string1" />
  15. <entry key="2" value="string2" />
  16. <entry key="3" value="string3" />
  17. <entry key="4" value="String4" />
  18. </map>
  19. </property>
  20. </bean>
  21. </beans>

ApplicationContextFactory.java

[java] view
plain
copy
  1. package study.spring.context.factory;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class ApplicationContextFactory {
  5. private static ApplicationContext ctx;
  6. private ApplicationContextFactory() {
  7. }
  8. public static ApplicationContext createInstance() {
  9. if (ctx == null) {
  10. ctx = new ClassPathXmlApplicationContext(
  11. new String[] { "spring-beans.xml" });
  12. }
  13. return ctx;
  14. }
  15. }

SpElUtil.java

[java] view
plain
copy
  1. package study.spring.beans;
  2. import java.util.Date;
  3. import java.util.List;
  4. import java.util.Map;
  5. import org.springframework.expression.Expression;
  6. import org.springframework.expression.ExpressionParser;
  7. import org.springframework.expression.spel.standard.SpelExpressionParser;
  8. public class SpElUtil {
  9. private Date time;
  10. private String name;
  11. private SpelTestInnerClass innerClass = new SpelTestInnerClass(
  12. "innerClass", 29);
  13. private List<Integer> numbers;
  14. private Map<Integer, String> maps;
  15. public static Object sayHelloForSpEl(String express) {
  16. ExpressionParser exp = new SpelExpressionParser();
  17. Expression ex = exp.parseExpression(express);
  18. return ex.getValue();
  19. }
  20. /**
  21. * 自定义方法
  22. *
  23. * @param string
  24. * @return
  25. */
  26. public static int len(String string) {
  27. return string.length();
  28. }
  29. public Map<Integer, String> getMaps() {
  30. return maps;
  31. }
  32. public void setMaps(Map<Integer, String> maps) {
  33. this.maps = maps;
  34. }
  35. public List<Integer> getNumbers() {
  36. return numbers;
  37. }
  38. public void setNumbers(List<Integer> numbers) {
  39. this.numbers = numbers;
  40. }
  41. public Date getTime() {
  42. return time;
  43. }
  44. public void setTime(Date time) {
  45. this.time = time;
  46. }
  47. public String getName() {
  48. return name;
  49. }
  50. public void setName(String name) {
  51. this.name = name;
  52. }
  53. public SpelTestInnerClass getInnerClass() {
  54. return innerClass;
  55. }
  56. public void setInnerClass(SpelTestInnerClass innerClass) {
  57. this.innerClass = innerClass;
  58. }
  59. }
  60. class SpelTestInnerClass {
  61. private String name;
  62. private int age;
  63. public SpelTestInnerClass(String name, int age) {
  64. this.name = name;
  65. this.age = age;
  66. }
  67. public boolean isGt30ForAge() {
  68. return this.age > 30 ? true : false;
  69. }
  70. public String getName() {
  71. return name;
  72. }
  73. public int getAge() {
  74. return age;
  75. }
  76. public void setAge(int age) {
  77. this.age = age;
  78. }
  79. }

SpElUtilTest.java

[java] view
plain
copy
  1. package study.spring.beans;
  2. import static org.junit.Assert.*;
  3. import java.util.ArrayList;
  4. import java.util.Arrays;
  5. import java.util.Date;
  6. import java.util.HashMap;
  7. import java.util.List;
  8. import java.util.Map;
  9. import org.junit.After;
  10. import org.junit.Before;
  11. import org.junit.Test;
  12. import org.springframework.context.ApplicationContext;
  13. import org.springframework.expression.Expression;
  14. import org.springframework.expression.ExpressionParser;
  15. import org.springframework.expression.common.TemplateParserContext;
  16. import org.springframework.expression.spel.standard.SpelExpressionParser;
  17. import org.springframework.expression.spel.support.StandardEvaluationContext;
  18. import study.spring.context.factory.ApplicationContextFactory;
  19. public class SpElUtilTest {
  20. // spring配置文件上下文
  21. ApplicationContext context = null;
  22. // spring el测试辅助类
  23. SpElUtil spel = null;
  24. // 表达式解析对象
  25. ExpressionParser exp = null;
  26. // 标准赋值上下文
  27. StandardEvaluationContext secontext;
  28. @Before
  29. public void setUp() throws Exception {
  30. context = ApplicationContextFactory.createInstance();
  31. spel = context.getBean(SpElUtil.class);
  32. secontext = new StandardEvaluationContext(spel);
  33. exp = new SpelExpressionParser();
  34. }
  35. @After
  36. public void tearDown() throws Exception {
  37. context = null;
  38. spel = null;
  39. secontext = null;
  40. exp = null;
  41. }
  42. /**
  43. * 文字表达式测试用例
  44. *
  45. * @throws Exception
  46. */
  47. @Test
  48. public void testSpELLiteralExpression() throws Exception {
  49. // 定义各种文字表达式
  50. String[] lELs = { "'hello SpEL'", "1.028E+7", "0x12EF", "true", "null" };
  51. assertEquals("hello SpEL",
  52. exp.parseExpression(lELs[0]).getValue(String.class));
  53. assertEquals(new Double(10280000), exp.parseExpression(lELs[1])
  54. .getValue(Double.class));
  55. assertEquals(new Integer(4847),
  56. exp.parseExpression(lELs[2]).getValue(Integer.class));
  57. assertTrue(exp.parseExpression(lELs[3]).getValue(Boolean.class));
  58. assertNull(exp.parseExpression(lELs[4]).getValue());
  59. }
  60. /**
  61. * 访问属性、数组、集合和 map 测试
  62. *
  63. * @throws Exception
  64. */
  65. @Test
  66. public void testSpELProOrArrayOrIndexEtcExpression() throws Exception {
  67. // 属性测试。time为SpElUtil类Date型数据,这里调用Date的属性Year
  68. assertEquals(new Integer(2011), exp.parseExpression("time.Year + 1900")
  69. .getValue(secontext, Integer.class));
  70. // 属性测试。innerClass为SpElUtil类中引入的其他类。
  71. assertEquals(29,
  72. exp.parseExpression("innerClass.age").getValue(secontext));
  73. // 设置SpElUtil类的numbers属性
  74. spel.setNumbers(Arrays.asList(2, 3, 4, 5, 6, 7, 9));
  75. // 访问对象属性数组通过索引
  76. assertEquals(2, exp.parseExpression("numbers[0]").getValue(secontext));
  77. // 访问map
  78. assertEquals("string1",
  79. exp.parseExpression("maps[1]")
  80. .getValue(secontext, String.class));
  81. }
  82. /**
  83. * 内联list测试
  84. *
  85. * @throws Exception
  86. */
  87. @SuppressWarnings({ "unchecked", "rawtypes" })
  88. @Test
  89. public void testSpELInnerListExpression() throws Exception {
  90. // 构造list
  91. List<String> nums = (List<String>) exp.parseExpression(
  92. "{'a','b','c','d'}").getValue();
  93. assertEquals(Arrays.asList("a", "b", "c", "d"), nums);
  94. // 构造List<List<>>
  95. List listOfLists = (List) exp.parseExpression("{{1,2},{3,4}}")
  96. .getValue(secontext);
  97. assertEquals(Arrays.asList(1, 2), listOfLists.get(0));
  98. }
  99. /**
  100. * Array 构造测试
  101. *
  102. * @throws Exception
  103. */
  104. @Test
  105. public void testSpELArrayConstructionExcpression() throws Exception {
  106. // 创建没有初始值的数组
  107. int[] a = (int[]) exp.parseExpression("new int[4]").getValue();
  108. assertEquals(4, a.length);
  109. // 创建带有初始值的数组
  110. int[] b = (int[]) exp.parseExpression("new int[4]{1,2,3,4}").getValue();
  111. assertEquals(3, b[2]);
  112. // 创建二维数组
  113. int[][] c = (int[][]) exp.parseExpression("new int[4][5]").getValue();
  114. assertEquals(4, c.length);
  115. assertEquals(5, c[0].length);
  116. }
  117. /**
  118. * 方法表达式测试
  119. *
  120. * @throws Exception
  121. */
  122. @Test
  123. public void testSpELMethodExcpression() throws Exception {
  124. // String.replace方法测试
  125. assertEquals(
  126. "abC2def",
  127. exp.parseExpression("'abcdef'.replace('c','C2')").getValue(
  128. String.class));
  129. // 自定义类方法测试
  130. assertFalse(exp.parseExpression("innerClass.isGt30ForAge()").getValue(
  131. secontext, Boolean.class));
  132. spel.getInnerClass().setAge(34);
  133. assertTrue(exp.parseExpression("innerClass.isGt30ForAge()").getValue(
  134. secontext, Boolean.class));
  135. }
  136. /**
  137. * 操作符、正则表达式测试
  138. *
  139. * @throws Exception
  140. */
  141. @Test
  142. public void testSpElOperatorAndRegExpression() throws Exception {
  143. // 关系操作
  144. assertTrue(exp.parseExpression("1 == 1").getValue(Boolean.class));
  145. assertTrue(exp.parseExpression("1 eq 1").getValue(Boolean.class));
  146. assertTrue(exp.parseExpression("1 > -1").getValue(Boolean.class));
  147. assertTrue(exp.parseExpression("1 gt -1").getValue(Boolean.class));
  148. assertTrue(exp.parseExpression("'a' < 'b'").getValue(Boolean.class));
  149. assertTrue(exp.parseExpression("'a' lt 'b'").getValue(Boolean.class));
  150. assertTrue(exp.parseExpression(
  151. " new Integer(123) instanceof T(Integer) ").getValue(
  152. Boolean.class));
  153. assertTrue(exp.parseExpression("'5.00' matches '^-?//d+(//.//d{2})?$'")
  154. .getValue(Boolean.class));
  155. // 逻辑操作
  156. assertTrue(exp.parseExpression("true and true").getValue(Boolean.class));
  157. assertTrue(exp.parseExpression("true or false").getValue(Boolean.class));
  158. assertFalse(exp.parseExpression("innerClass.isGt30ForAge() and false ")
  159. .getValue(secontext, Boolean.class));
  160. assertFalse(exp.parseExpression("!innerClass.isGt30ForAge() and true ")
  161. .getValue(secontext, Boolean.class));
  162. assertTrue(exp.parseExpression("!false").getValue(Boolean.class));
  163. // 运算操作
  164. assertEquals(2, exp.parseExpression("1 + 1").getValue());
  165. assertEquals("ABab",
  166. exp.parseExpression("'AB' + 'ab'").getValue(String.class));
  167. assertEquals(25.0,
  168. exp.parseExpression("1 + 2 * 8 div 4 mod 2 + 2 ^ 3 * 3e0")
  169. .getValue());
  170. assertEquals(exp.parseExpression("1 + 2 * 8 / 4 % 2 + 2 ^ 3 ")
  171. .getValue(),
  172. exp.parseExpression("1 + 2 * 8 div 4 mod 2 + 2 ^ 3 ")
  173. .getValue());
  174. }
  175. /**
  176. * 赋值表达式测试
  177. *
  178. * @throws Exception
  179. */
  180. @SuppressWarnings("deprecation")
  181. @Test
  182. public void testSpelAssignmentExpression() throws Exception {
  183. Date oldDate = spel.getTime();// 获取当前time属性值
  184. exp.parseExpression("time").setValue(secontext, new Date(113, 2, 25)); // 为time属性重新赋值
  185. Date newDate = spel.getTime();// 获取赋值后的time属性值
  186. assertEquals(2013,
  187. exp.parseExpression("time.Year + 1900").getValue(secontext));
  188. assertNotSame(oldDate, newDate);
  189. // 或者使用下属方法赋值
  190. assertEquals("abc",
  191. exp.parseExpression("Name = 'abc'").getValue(secontext));
  192. // 还原time默认,避免后续测试错误
  193. spel.setTime(oldDate);
  194. spel.setName("override");
  195. }
  196. /**
  197. * 类型操作表达式测试
  198. *
  199. * @throws Exception
  200. */
  201. @SuppressWarnings("rawtypes")
  202. @Test
  203. public void testSpelTypesExpression() throws Exception {
  204. Class dateClass = exp.parseExpression("T(java.util.Date)").getValue(
  205. Class.class);
  206. assertEquals("java.util.Date", dateClass.getName());
  207. assertTrue(exp
  208. .parseExpression(
  209. "T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR")
  210. .getValue(Boolean.class));
  211. }
  212. /**
  213. * 构造函数调用测试
  214. *
  215. * @throws Exception
  216. */
  217. @Test
  218. public void testSpelConstructorsExpression() throws Exception {
  219. SpelTestInnerClass spt = exp
  220. .parseExpression(
  221. "new study.spring.beans.SpelTestInnerClass('constructTest',23)")
  222. .getValue(SpelTestInnerClass.class);
  223. assertEquals(23, spt.getAge());
  224. assertEquals("constructTest", spt.getName());
  225. }
  226. /**
  227. * 设置变量测试
  228. *
  229. * @throws Exception
  230. */
  231. @SuppressWarnings("unchecked")
  232. @Test
  233. public void testSpelVariablesExpression() throws Exception {
  234. List<Integer> list = new ArrayList<Integer>();
  235. list.addAll(Arrays.asList(2, 3, 4, 5, 6, 7, 9));
  236. secontext.setVariable("list", list);
  237. List<Integer> vList = (List<Integer>) exp.parseExpression("#list")
  238. .getValue(secontext);
  239. assertEquals(vList, list);
  240. List<Integer> nums = (List<Integer>) exp.parseExpression(
  241. "#list.?[#this >5]").getValue(secontext); // 获取值大于5的元素集合
  242. assertEquals(nums, Arrays.asList(6, 7, 9));
  243. }
  244. /**
  245. * 自定义函数表达式测试
  246. *
  247. * @throws Exception
  248. */
  249. @Test
  250. public void testSpelFunctionExpression() throws Exception {
  251. StandardEvaluationContext context = new StandardEvaluationContext();
  252. context.registerFunction("len", SpElUtil.class.getDeclaredMethod("len",
  253. new Class[] { String.class }));
  254. assertEquals(3, exp.parseExpression("#len('abc')").getValue(context));
  255. }
  256. @Test
  257. public void testSpelBeanExpression() throws Exception {
  258. }
  259. /**
  260. * 三元操作测试
  261. *
  262. * @throws Exception
  263. */
  264. @Test
  265. public void testSpelTernaryOperatorExpression() throws Exception {
  266. assertTrue(exp.parseExpression(" true ? true :false").getValue(
  267. Boolean.class));
  268. assertEquals("is true",
  269. exp.parseExpression(" 1 == 1 ? 'is true' :'is false'")
  270. .getValue(String.class));
  271. }
  272. /**
  273. * Elvis 操作测试
  274. *
  275. * @throws Exception
  276. */
  277. @Test
  278. public void testSpeleElvisOperatorExpression() throws Exception {
  279. Expression ex = exp.parseExpression("name?:'name is null'");
  280. assertEquals("override", ex.getValue(secontext, String.class));
  281. spel.setName(null);
  282. assertEquals("name is null", ex.getValue(secontext, String.class));
  283. spel.setName("override");
  284. }
  285. /**
  286. * 安全导航操作测试
  287. *
  288. * @throws Exception
  289. */
  290. @Test
  291. public void testSpelSafeNavOperatorExpression() throws Exception {
  292. assertEquals("innerClass", exp.parseExpression("innerClass?.name")
  293. .getValue(secontext, String.class));
  294. spel.setInnerClass(null);
  295. // 使用这种表达式可以避免抛出空指针异常
  296. assertNull(exp.parseExpression("innerClass?.name").getValue(secontext,
  297. String.class));
  298. }
  299. /**
  300. * 集合选择表达式测试
  301. *
  302. * @throws Exception
  303. */
  304. @SuppressWarnings("unchecked")
  305. @Test
  306. public void testSpelCollectionSelectExpression() throws Exception {
  307. spel.setNumbers(Arrays.asList(2, 3, 4, 5, 6, 7, 9));
  308. List<Integer> nums = (List<Integer>) exp.parseExpression(
  309. "numbers.?[#this >5]").getValue(secontext);
  310. assertEquals(nums, Arrays.asList(6, 7, 9));
  311. // 获取第一个元素
  312. assertEquals(6,
  313. exp.parseExpression("numbers.^[#this > 5]").getValue(secontext));
  314. // 获取最后一个元素
  315. assertEquals(9,
  316. exp.parseExpression("numbers.$[#this > 5]").getValue(secontext));
  317. Map<Integer, String> maps = (Map<Integer, String>) exp.parseExpression(
  318. "maps.?[value == 'string3' ]").getValue(secontext);
  319. Map<Integer, String> tmap = new HashMap<Integer, String>();
  320. tmap.put(3, "string3");
  321. assertEquals(maps, tmap);
  322. Map<Integer, String> mapk = (Map<Integer, String>) exp.parseExpression(
  323. "maps.?[key > 2 and key < 4 ]").getValue(secontext);
  324. assertEquals(mapk, tmap);
  325. }
  326. /**
  327. * 投影表达式测试
  328. *
  329. * @throws Exception
  330. */
  331. @SuppressWarnings("unchecked")
  332. @Test
  333. public void testSpelProjectionExpression() throws Exception {
  334. spel.setNumbers(Arrays.asList(2, 3, 4, 5, 6));
  335. assertEquals(Arrays.asList(5, 6, 7, 8, 9),
  336. exp.parseExpression("numbers.![#this+3]").getValue(secontext));
  337. List<Integer> keys = (List<Integer>) exp.parseExpression("maps.![key]")
  338. .getValue(secontext);
  339. assertEquals(keys, Arrays.asList(1, 2, 3, 4));
  340. List<String> mapv = (List<String>) exp.parseExpression("maps.![value]")
  341. .getValue(secontext);
  342. assertEquals(mapv,
  343. Arrays.asList("string1", "string2", "string3", "String4"));
  344. List<Boolean> mapK = (List<Boolean>) exp.parseExpression(
  345. "maps.![key > 2 and value !='String4']").getValue(secontext);
  346. assertEquals(mapK, Arrays.asList(false, false, true, false));
  347. }
  348. /**
  349. * 模板语言测试
  350. *
  351. * @throws Exception
  352. */
  353. @Test
  354. public void testSpelTemplate() throws Exception {
  355. assertEquals(
  356. " this is a test 4",
  357. exp.parseExpression(" this is a test #{ maps.![key].get(3)}",
  358. new TemplateParserContext()).getValue(secontext,
  359. String.class));
  360. }
  361. }