这是本系列的第三篇。第二部分在这里
http://blog.hibernate.org/cgi-bin/blosxom.cgi/2007/07/09#ee6part2
JSF和JSP使用的新统一表达式语言API是Java平台的一个非常有用的补充。不幸的是,尽管在设计用于处理统一表达式语言的Java级API上投入了大量的精力,但自JSP初期以来,表达式语言本身并没有发生太大的变化。现在,引入一些新特性已经刻不容缓。更强大的表达式语言让我们能够将展示逻辑保留在我们的页面上,并避免用额外的方法污染业务模型。
以下是我的一些建议,尽管我对建议的语法并不十分执着。
方法参数
这是一个让人不禁要问“他们是怎么想的?”的时刻。统一表达式语言不支持带参数的方法表达式。真的。
建议的语法
customer.getOrder(ordernumber).product.name
switch语句
在JSP或JSF页面上,能够在一个单独的表达式中处理多个情况非常有用。
建议的语法
switch (order.status) { case OPEN: 'Open' case CLOSED: 'Closed' else '' }
日期和时间
目前,EL中还没有比较日期和时间的办法。<, >, <=和>=运算符应该扩展到支持java.util.Date。也许还应该引入日期/时间字面量的语法。
集合大小运算符
令人惊讶的是,EL中还没有简单的方法来确定集合的大小!
建议的语法
size customer.orders
这个运算符应该适用于任何Collection、Map、String或Iterable。此外,空运算符应该扩展到支持Map和Iterable。
集合构造函数
在定义页面时,能够迭代集合字面量非常有用。
创建java.util.List实例的建议语法
{'foo', 'bar', 'baz'}
创建java.util.Map实例的建议语法
{'foo'->1, 'bar'->3}
创建指定整数范围java.util.List实例的建议语法
{1...100}
集合迭代
这个特性是一种简化的闭包支持。它应该适用于所有Iterable的实例。
以下建议的语法返回列表 {2, 3, 4}
{1, 2, 3} collect { x -> x+1 }
以下返回 {2, 3}
{1, 2, 3} select { x -> x>1 }
以下返回对象 2
{1, 2, 3} detect { x -> x>1 }
以下返回对象 3
{1, 2, 3} detect { max, x -> max>=x }
以下返回 {3, 2, 1}
{1, 2, 3} desc
以下按名称排序客户
customers asc { c -> customer.name }
另一种方法可能是在 Python 的列表推导式中进行复制
[ x+1 for x in {1, 2, 3} where x>1 ]
这会得到 {3, 4}。
结论
这不是要将统一表达式语言(Unified EL)变成一种编程语言。实际上,我更喜欢它比 OGNL 或 MVEL 更为简单。相反,目的是消除某些痛点,在这些痛点中,当前唯一的解决方案是回退到在 Java 代码中编写表现层逻辑。
统一表达式语言(Unified EL)的另一种改进方法是允许 JSF/JSP 表达式用 JavaScript、Groovy 或其他脚本语言编写。我对这个持开放态度,当然可以在统一表达式语言(Unified EL)表达式工厂后面包装 JavaScript 解释器。但我担心这会将人们推向错误的方向,编写包含过程化代码的模板。我最不想看到的是类似 .rhtml 文件的 JSF 模板 ;-)