http://leeyee.github.io/blog/2011/06/19/spring-expression-language/

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

  • 文本表达式
  • 布尔类和关系操作
  • 正则表达式
  • 类表达式
  • 访问属性、数组、集合和map
  • 方法调用
  • 关系操作
  • 赋值操作
  • 调用构造函数
  • Bean 引用
  • 数组构造
  • 内联list
  • 三元操作
  • 变量
  • 用户自定义函数
  • 集合投影
  • 集合选择
  • 模板表达式

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

第一步,构建解析

  1. ExpressionParser parser = new SpelExpressionParser();

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

  1. Expression exp = parser.parseExpression( SpEl);

第三步,获取结果

  1. exp.getValue()

2.1 文本表达式

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

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

  1. String[] lELs = { "'hello SpEL'", "1.028E+7", "0x12EF", "true", "null" };
  2. assertEquals("hello SpEL",
  3. exp.parseExpression(lELs[0]).getValue(String.class));
  4. assertEquals(new Double(10280000), exp.parseExpression(lELs[1])
  5. .getValue(Double.class));
  6. assertEquals(new Integer(4847),
  7. exp.parseExpression(lELs[2]).getValue(Integer.class));
  8. assertTrue(exp.parseExpression(lELs[3]).getValue(Boolean.class));
  9. assertNull(exp.parseExpression(lELs[4]).getValue());

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

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

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

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

  1. // 属性测试。time为SpElUtil类Date型数据,这里调用Date的属性Year
  2. assertEquals(new Integer(2011), exp.parseExpression("time.Year + 1900")
  3. .getValue(secontext, Integer.class));
  4. // 属性测试。innerClass为SpElUtil类中引入的其他类。
  5. assertEquals(29,
  6. exp.parseExpression("innerClass.age").getValue(secontext));
  7. // 设置SpElUtil类的numbers属性
  8. spel.setNumbers(Arrays.asList(2, 3, 4, 5, 6, 7, 9));
  9. // 访问对象属性数组通过索引
  10. assertEquals(2, exp.parseExpression("numbers[0]").getValue(secontext));
  11. // 访问map
  12. assertEquals("string1",
  13. exp.parseExpression("maps[1]")
  14. .getValue(secontext, String.class));

2.3 内置列表

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

  1. // 构造list
  2. List<String> nums = (List<String>) exp.parseExpression(
  3. "{'a','b','c','d'}").getValue();
  4. assertEquals(Arrays.asList("a", "b", "c", "d"), nums);
  5. // 构造List<List<>>
  6. List listOfLists = (List) exp.parseExpression("{ {1,2},{3,4} }")
  7. .getValue(secontext);
  8. assertEquals(Arrays.asList(1, 2), listOfLists.get(0));

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

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

  1. // 创建没有初始值的数组
  2. int[] a = (int[]) exp.parseExpression("new int[4]").getValue();
  3. assertEquals(4, a.length);
  4. // 创建带有初始值的数组
  5. int[] b = (int[]) exp.parseExpression("new int[4]{1,2,3,4}").getValue();
  6. assertEquals(3, b[2]);
  7. // 创建二维数组
  8. int[][] c = (int[][]) exp.parseExpression("new int[4][5]").getValue();
  9. assertEquals(4, c.length);
  10. assertEquals(5, c[0].length);

2.5 方法调用

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

  1. assertEquals(
  2. "abC2def",
  3. exp.parseExpression("'abcdef'.replace('c','C2')").getValue(
  4. String.class));
  5. // 自定义类方法测试
  6. assertFalse(exp.parseExpression("innerClass.isGt30ForAge()").getValue(
  7. secontext, Boolean.class));
  8. spel.getInnerClass().setAge(34);
  9. assertTrue(exp.parseExpression("innerClass.isGt30ForAge()").getValue(
  10. secontext, Boolean.class));

2.6 操作符

2.6.1 关系操作符

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

  1. assertTrue(exp.parseExpression("1 == 1").getValue(Boolean.class));
  2. assertTrue(exp.parseExpression("1 eq 1").getValue(Boolean.class));
  3. assertTrue(exp.parseExpression("1 > -1").getValue(Boolean.class));
  4. assertTrue(exp.parseExpression("1 gt -1").getValue(Boolean.class));
  5. assertTrue(exp.parseExpression("'a' < 'b'").getValue(Boolean.class));
  6. assertTrue(exp.parseExpression("'a' lt 'b'").getValue(Boolean.class));
  7. assertTrue(exp.parseExpression(
  8. " new Integer(123) instanceof T(Integer) ").getValue(
  9. Boolean.class));
  10. assertTrue(exp.parseExpression("'5.00' matches '^-?\\d+(\\.\\d{2})?$'")
  11. .getValue(Boolean.class));

2.6.2 逻辑操作符

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

  1. assertTrue(exp.parseExpression("true and true").getValue(Boolean.class));

2.6.3 数学运算操作符

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

  1. assertEquals(25.0,
  2. exp.parseExpression("1 + 2 * 8 div 4 mod 2 + 2 ^ 3 * 3e0")
  3. .getValue());

2.7 赋值操作

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

  1. Date oldDate = spel.getTime();// 获取当前time属性值
  2. exp.parseExpression("time").setValue(secontext, new Date(113, 2, 25)); // 为time属性重新赋值
  3. Date newDate = spel.getTime();// 获取赋值后的time属性值
  4. assertEquals(2013,
  5. exp.parseExpression("time.Year + 1900").getValue(secontext));
  6. assertNotSame(oldDate, newDate);
  7. // 或者使用下属方法赋值
  8. assertEquals("abc",
  9. exp.parseExpression("Name = 'abc'").getValue(secontext));

2.8 类型

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

  1. Class dateClass = exp.parseExpression("T(java.util.Date)").getValue(Class.class);
  2. assertEquals("java.util.Date", dateClass.getName());
  3. assertTrue(exp
  4. .parseExpression(
  5. "T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR")
  6. .getValue(Boolean.class));

2.9 构造器

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

  1. SpelTestInnerClass spt = exp
  2. .parseExpression(
  3. "new leeyee.study.spring3.bean.SpelTestInnerClass('constructTest',23)")
  4. .getValue(SpelTestInnerClass.class);

2.10 变量

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

  1. List<Integer> list = new ArrayList<Integer>();
  2. list.addAll(Arrays.asList(2, 3, 4, 5, 6, 7, 9));
  3. secontext.setVariable("list", list);
  4. List<Integer> vList = (List<Integer>) exp.parseExpression("#list")
  5. .getValue(secontext);
  6. assertEquals(vList, list);

2.10.1 #this变量

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

  1. List<Integer> nums = (List<Integer>) exp.parseExpression(
  2. "#list.?[#this >5]").getValue(secontext); // 获取值大于5的元素集合
  3. assertEquals(nums, Arrays.asList(6, 7, 9));

2.11 用户自定义函数

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

  1. context.registerFunction("len", SpElUtil.class.getDeclaredMethod("len",
  2. new Class[] { String.class }));
  3. assertEquals(3, exp.parseExpression("#len('abc')").getValue(context));

2.12 三元操作

  1. assertTrue(exp.parseExpression(" true ? true :false").getValue(
  2. Boolean.class));

2.13 Elvis操作

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

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

  1. @Value("#systemPro['mail.port'] ? : 25}")
  2. // 当mail.port为空时将默认为25
  3. Expression ex = exp.parseExpression("name?:'name is null'");
  4. assertEquals("override", ex.getValue(secontext, String.class));
  5. spel.setName(null);
  6. assertEquals("name is null", ex.getValue(secontext, String.class));
  7. spel.setName("override");

2.14 安全导航操作

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

  1. assertEquals("innerClass", exp.parseExpression("innerClass?.name")
  2. .getValue(secontext, String.class));
  3. spel.setInnerClass(null);
  4. // 使用这种表达式可以避免抛出空指针异常
  5. assertNull(exp.parseExpression("innerClass?.name").getValue(secontext,
  6. String.class));

2.15 集合选择

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

选择的语法为?[selectionExpression]。他将过滤集合并且返回一个新的集合(原集合的子集)。选择语句也可用在Map中,过滤keySet及valueSet分别使用key和value关键字。另外:选择语法中,选择符合条件的结果集的第一个元素的语法为 ^[selectionExpression],选择最后一个元素的语法为$[selectionExpression]

  1. spel.setNumbers(Arrays.asList(2, 3, 4, 5, 6, 7, 9));
  2. List<Integer> nums = (List<Integer>) exp.parseExpression(
  3. "numbers.?[#this >5]").getValue(secontext);
  4. assertEquals(nums, Arrays.asList(6, 7, 9));
  5. // 获取第一个元素
  6. assertEquals(6,
  7. exp.parseExpression("numbers.^[#this > 5]").getValue(secontext));
  8. // 获取最后一个元素
  9. assertEquals(9,
  10. exp.parseExpression("numbers.$[#this > 5]").getValue(secontext));
  11. Map<Integer, String> maps = (Map<Integer, String>) exp.parseExpression(
  12. "maps.?[value == 'string3' ]").getValue(secontext);
  13. Map<Integer, String> tmap = new HashMap<Integer, String>();
  14. tmap.put(3, "string3");
  15. assertEquals(maps, tmap);
  16. Map<Integer, String> mapk = (Map<Integer, String>) exp.parseExpression(
  17. "maps.?[key > 2 and key < 4 ]").getValue(secontext);
  18. assertEquals(mapk, tmap);

2.16 集合投影

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

  1. assertEquals(Arrays.asList(5, 6, 7, 8, 9), exp
  2. .parseExpression("numbers.![#this+3]").getValue(secontext));

2.17 模板表达式

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

  1. assertEquals(
  2. " this is a test 4",
  3. exp.parseExpression(" this is a test #{ maps.![key].get(3)}",
  4. new TemplateParserContext()).getValue(secontext,
  5. String.class));

一大段测试用例:

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

Spring3 表达式语言(SpEL)介绍相关推荐

  1. Sping-Spring表达式语言SpEL

    概述 SpEL:字面量 SpEL:引用 Bean.属性和方法 引用其他对象 引用其他对象的属性 调用其他方法,还可以链式操作 调用静态方法或静态属性 SpEL支持的运算符号 算数运算符:+, -, * ...

  2. SpringEL 表达式语言(Spring Expression Language)

    Spring学习总结:表达式语言 Spring Expression Language 目录 SpEL简介与功能特性 一.为什么需要Spring表达式语言 二.SpEL表达式Hello World! ...

  3. Spring学习总结(四)——表达式语言 Spring Expression Language

    SpEL简介与功能特性 Spring表达式语言(简称SpEL)是一个支持查询并在运行时操纵一个对象图的功能强大的表达式语言.SpEL语言的语法类似于统一EL,但提供了更多的功能,最主要的是显式方法调用 ...

  4. 开涛spring3(5.15.2) - Spring表达式语言 之 5.1 概述 5.2 SpEL基础

    5.1  概述 5.1.1  概述 Spring表达式语言全称为"Spring Expression Language",缩写为"SpEL",类似于Struts ...

  5. Spring3的表达式语言

    Spring表达式语言全称为"Spring Expression Language",缩写为"SpEL",类似于Struts2x中使用的OGNL表达式语言, 能 ...

  6. sple表达式_学习Spring表达式语言(SpEL)

    概观 Spring Expression Language(缩写为SpEL)是一种强大的表达式语言.在Spring产品组合中,它是表达式计算的基础.它支持在运行时查询和操作对象图,它可以与基于XML和 ...

  7. OGNL表达式语言介绍

    OGNL介绍 OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言(Expression Language,简称为EL),通过它简单一致的表达 ...

  8. Spring 表达式语言(SpEL)

    本文纯属spring官方文档翻译版,详情请参考:Core Technologies Spring 表达式语言(简称"SpEL"),Spring Expression Languag ...

  9. Spring EL 表达式的简单介绍和使用

    文章目录 1. 简单介绍 1.1. 什么是 Spring EL 1.2. 为什么要使用 Spring EL 1.3. 如何使用 Spring EL 2. 简单使用 3. EL 表达式解析引擎 3.1. ...

最新文章

  1. FPGA/IC技术交流2020
  2. Android 实现歌词变红效果
  3. ASP.NET MVC 3 RC发布
  4. redis持久化实现原理
  5. 控制src_【聚焦】仙知机器人基于SRC的激光SLAM自动叉车,满足各类场景需求
  6. 初识RabbitMQ,附RabbitMQ+PHP演示实例(亲测通过)
  7. nagios报Connection refused by host的解决办法
  8. linux 修改文件名_Linux常用命令
  9. 邹建老大写的经典SQL
  10. 服务器性能低下时正确的处理方法
  11. HDU [1529] || POJ [P1275] Cashier Employment
  12. XMPP聊天环境配置
  13. 中limit怎末用_Nginx配置——关于limit_conn_zone和limit_conn
  14. App制作开发工具源代码搭建网站转app网站
  15. 矩阵分析及应用(1-2章)
  16. PowerBuilder 2018
  17. 数据大屏产品介绍PPT_【达索系统】 Ortems APS产品介绍 PPT
  18. 小米手机连接电脑只能看到部分相片_小米手机连接电脑后怎么看照片?
  19. android ios mp4格式转换,爱思助手怎么转换视频格式 爱思助手将普通视频格式转换为mp4格式方法...
  20. 讯飞2021年营收183亿:同比增41% 净利为15.56亿

热门文章

  1. 电脑下载python多少位的在哪看-python64位
  2. 学python买什么书好-学python3什么书好
  3. python叫什么-python中什么叫类
  4. python能做软件开发吗-python代码能做成软件吗
  5. python培训班一般多少钱-报个python培训班多少钱
  6. python搞笑代码-【转】 Python 程序员的进化--搞笑版
  7. python3.8.5 run-Python 3.8.5 正式发布
  8. python语言教程-Python语言教程手册
  9. python是c语言写的吗-学习python还是c语言?
  10. mybatis中statementHandler的设计与实现