1.了解表达式语言

表达式语言(EL)用于在不使用脚本、声明或者表达式的情况下,在JSP页面中渲染数据。

EL曾是JSTL 1.0规范(与JSP 1.2)中的一部分,并且只可以用作JSTL标签的特性。

到了JSP 2.0和JSTL1.1,由于EL的流行,它的规范从JSTL规范移动到了JSP规范中,并且在JSP的任何部位都可以使用,不再限制于JSTL标签特性中。

到了Java EE 7,它被移动到了自己的JSR(JSR 341)中,并更新了对Lambda表达式和Java Collections Stream API的支持,这标志着Java统一表达式语言3.0的产生(简称EL3.0)。

1.1 基本语法

JSP转换器必须要能够检测到EL表达式的开始和结束,并能与页面的其他部分区分开,然后正确地解析和执行表达式。

基本的EL语法有两种不同的类型:

  • 立即执行
  • 延迟执行

立即执行

因为JSP从上向下执行,这意味着EL表达式将在JSP引擎发现它,并在继续执行其他页面部分之前执行它。

${expr},其中expr是一个有效的EL表达式。

\${not an EL expression}不是EL表达式(美元符号之前的后斜线将告诉JSP引擎这并不是一个EL表达式),它将被按照字面内容输出到响应中。还可以使用美元符号的XML实体$取代\$,结果是相同的,${not an EL expression}

当然,有时也需要在表达式之前添加后斜线,但仍然希望表达式执行。这时就必须使用后斜线的XML实体,\${EL expression to evaluate}

延迟执行

延迟执行EL主要用于满足JavaServer Faces的需要,#{expr}

添加EL表达式

  • EL表达式不能用再任何指令中。在编译JSP时,指令(<%@ page %><%@ include %><%@ taglib %>)将会被执行,但EL表达式是在稍后渲染JSP时执行。
  • JSP声明<%! %>、脚本<% %>或者表达式<%= %>中的EL表达式也是无效的。

除此之外,EL表达式可以添加到其他任何位置。

  • 将EL表达式内嵌在文本中显示到屏幕, The user will see ${expr} text and will know that ${expr} is good.
  • 表达式还可以用在标准的HTML标签特性中,<input type="text" name="something" value="${expr}" />
  • 在JSP标签特性中也可以使用。
<c:url value="/something/${expr}/${expr}" />
<c:redirect url="${expr}" />

EL表达式可以只是特性值的一部分。

在JavaScript和层叠样式表中也可以包含EL表达式:

<script type="text/javascript" lang="javascript">
var employeeName = '${expr}';
var booleanValue = '${expr}';
var numericValue = '${expr}';
</script>
<style type="text/css">
span.error{
color: ${expr};
background-image: url('/some/place/${expr}.png');
}
</style>

2.使用EL语法

EL语法是弱类型,并且它包含了许多内建的隐式类型转换。

表达式主要的规则是执行后要产生某个值。不能在表达式中声明变量、执行赋值语句或者不产生结果的操作。

使用EL表达式是为了避免在JSP中使用Java。

在EL3.0规范中可以在表达式中为变量赋值,${x=5}将把5赋给x,并且在页面中渲染出EL表达式中的5。

2.1 EL表达式的关键字

  • empty用于验证某些集合、Map或者数组是否含有值,或者某些字符串是否含有一个或多个字符。如果它们为null或者“空”,那么表达式的结果为真;否则,结果为假,${empty x}
  • 关键字divmod分别对应着/(除法)和%(求余),它们只是数学运算符的替代关键字。如果愿意的话,你仍然可以使用/%
  • 关键字andornot分别对应着Java逻辑运算符&&||!
  • 关键字eqneltgtlege分别对应着Java逻辑运算符==!=<><=>=

2.2 操作符优先级

EL表达式的操作符有优先级,优先级相同的操作符将按照它们出现的顺序,从左向右执行。

操作符的优先级,从上(最高优先级)到下(最低优先级)显示:

[] .
()
一元运算符 - ! not empty
* / div % mod
数学运算符 + -
字符串连接 +=
< lt > gt <= le >= ge
== eq != ne
&& and
|| or
三元运算符 ? :
Lambda表达式 ->
赋值 =
在表达式中同时使用多个表达式 ;

2.2.1 字面量

EL表达式也有字符串字面量,EL中的字符串字面量既可以使用双引号也可以使用单引号。

<c:url value="${'value'}"/>
<c:url value='${"value"}'/>
<c:url value="${\"value\"}"/>
<c:url value='${\'value\'}'/>

如果字符串变量自身已经包含了单引号或双引号,必须将其中一些引号转义。

<c:url value="${'some \"value\"'}"/>
<c:url value='${"some \"value\""}'/>
<c:url value="${'some \'value\''}"/>
<c:url value='${"some \'value\'"}'/>
<c:url value="${\"some 'value'\"}"/>
<c:url value='${\'some "value"\'}'/>

如果可能,最好保持字符串字面量尽可能的简单。

EL表达式中的字符串字面量连接:

The user will see ${expr} text and will ${expr}.
${'The user will see ' += expr += " text and will " += expr += '.'}
${"The user will see " += expr += ' text and will ' += expr += "."}

如果某些对象中的expr结果不是字符串,它将被强制转型为字符串。

EL表达式使数学计算变得更简单,所以所有的类型转换和精度升级都将以隐式的方式完成。

在EL表达式中,只允许使用十进制字面量。

EL并未包含charbyteshort类型的字面量,但可以在必要的时候将其他字面量强制转型为charbyteshort

通过使用EL集合字面量可以构造集合、列表和Map,构造实例时将会使用它们的默认实现。

  • 字面量集合将会构造出HashSet<Object>{1, 2, 'three', 4.00, x}
  • 字面量列表将会构造出ArrayList<Object>[1, 2, 'three', [x, y], {'foo', 'bar'}]
  • 字面量Map将会构造出HashMap<Object, Object>{'one': 1, 2: 'two', 'key': x, 'list': [1, 2, 3] }

构造列表的方法与构造集合的方法基本一致,区别在于列表使用的是方括号,而集合使用的是花括号。

可以通过在一个集合对象中插入另一个集合对象的方式嵌套集合。

对象属性和方法

不可以在EL表达式中访问公开字段。假设现在有一个名为Shirt的类,它包含了一个公开字段size。通过${shirt.size}访问Shirt对象的size字段是行不通的。

现在对Shirt类进行修改,将size字段改为私有的,并为size字段提供getter和setter方法,就可以通过${shirt.size}访问Shirt对象的size字段了。

也可以使用[]操作符访问属性,${shirt["size"]}

通过EL可以在JSP中调用对象的方法,在调用一个需要传入参数并且具有返回值的函数时,方法调用特别有用。

静态字段和方法访问

表达式语言3.0中新增的特性,可以访问JSP类路径中任何类的公开静态字段和公开静态方法。

除非使用的类已经使用JSP page指令导入,否则必须使用完全限定的类名。记录:在JSP中,如同Java一样,所有在java.lang包中的类都已经被隐式地导入了。所以${java.lang.Integer.MAX_VALUE}可以被写为${Integer.MAX_VALUE}。必须要注意的是只可以读取这些字段的值,不能修改它们。

EL表达式还可以调用类的构造函数,它将返回一个该类的实例,可基于该实例进一步访问属性、调用方法或者将它强制转型为字符串用于输出。

${com.wrox.User()}
${com.wrox.User('First', 'Last').firstName}

枚举

从传统上来讲,EL中的枚举将在必要的时候被强制转型为字符串,或者从字符串强制转型为枚举。

例如,现在JSP中有一个局部变量dayOfWeek,它是Java 8新增的日期和时间API中java.time.DayOfWeek枚举的实例,测试dayOfWeek代表是不是星期六:${dayOfWeek == 'SATURDAY'}

变量dayOfWeek将被转换为字符串,但它并不是类型安全的。

到了EL 3.0,可以使用静态字段访问语法实现类型安全的枚举常量引用。毕竟,枚举常量只是他们枚举类型的公共静态的、不可改变的字段。

${dayOfWeek == java.time.DayOfWeek.SATURDAY}

lambda表达式

一个lambda表达式就是一个匿名函数。

EL中的lambda表达式体中可以包含任何对于Java方法来说合法的代码,而EL的lambda表达式体重包含的则是另一个EL表达式。

a -> a + 5
(a, b) -> a + b

使用了lambda表达式的EL表达式:

${(a -> a + 5)(4)}
${((a, b) -> a + b)(4,7)}

定义之后使用的lambda表达式,${v = (a, b) -> a + b; v(3, 15)}(第二个表达式的输出是18)。

lambda表达式作为参数传入到方法调用中,${users.stream().filter(u -> u.lastName == 'Williams' || u.lastName == 'Sanders').toArray()}

集合

EL可以使用点和中括号操作符轻松地访问集合。如何使用操作符取决于使用集合的类型。

访问Map的值的方式相当简单:

${map["username"]}
${map["userId"]}
${map.username}
${map.userId}

访问列表页同样的简单:

${list[0]}
${list[1]}
${list["0"]}
${list['1']}

EL允许使用字符串字面量代替数字用作列表索引,但所使用的字符串必须能够转换为整数。我们推荐使用数字字面量。

集合和队列不能通过EL访问,它们也没有访问方法,只能通过遍历的方式访问它们。

参考:《Java Web高级编程》

Java EE之表达式语言EL(上)的更多相关文章

  1. Java EE之表达式语言EL(下)

    1.在EL表达式中使用作用域变量 表达式语言对作用域变量的支持,以及它解析变量的方式都使它变得非常有用. 1.1 EL表达式的隐式变量 EL表达式的作用域中定义了11个隐式变量. 当EL表达式引用了一 ...

  2. 表达式语言EL

    表达式语言EL 表达式语言 EL(Expression Language,表达式语言)主要是用在JSP页面中,用来辅助我们产生无脚本的JSP页面,此处的脚本指的是JSP中的Java代码. EL的语法是 ...

  3. 表达式语言EL简单学习

    Jsp2.0最重要的特性就是表达式语言EL.jsp用户可以用它来访问应用程序数据. EL表达式以${开头并以}结束. ${expresion}     ${x+y} 它也常用来连接两个表达式,取值将从 ...

  4. 06.十分钟学会表达式语言EL

    一. 概念:MVC设计模式一个主要好处就是让jsp中的代码越来越来少,而且规定只能出现三种代码:接收属性,判断语句,迭代输出.但是,在开发中,jsp输出至少还是需要接受VO对象的,这时候为了避免导入V ...

  5. 【jsp】详解JSP表达式语言(EL)

    一.JSP EL语言定义 E L(Expression Language)  目的:为了使JSP写起来更加简单. 表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 ...

  6. Java EE之通过表单上传文件

    public class Ticket { private String customerName; private String subject; private String body; priv ...

  7. Java EE Expression Language

    什么是EL? 形如这样(立即执行的): ${sessionScope.cart.total} 或者这样(延迟执行的): #{customer.name} 的表达式语言(Expression Langu ...

  8. Java EE JSP内置对象及表达式语言

    一.JSP内置对象 JSP根据Servlet API规范提供了一些内置对象,开发者不用事先声明就可使用标准变量来访问这些对象. JSP提供了9种内置对象: (一).request 简述: JSP编程中 ...

  9. JSP简明教程(四):EL表达式语言、JavaBean、Cookie、Session

    EL表达式语言 EL这是Expression Language.的目的是为了简化JSP句法.来看几个例子来清除. ${test} 它会被翻译成<%=test%> ${test.name} ...

随机推荐

  1. 【资源分享】ArcFace Demo [Android]

    虹软人脸识别引擎Android的Demo演示,可以直接下载使用. 下载地址: https://github.com/asdfqwrasdf/ArcFaceDemo readme: 工程如何使用? 下载 ...

  2. ubuntu下解压rar文件

    ubuntu 下rar解压工具安装方法: 压缩功能 sudo apt-get install rar 1 解压功能 sudo apt-get install unrar 1 使用 可以直接在UI界面使 ...

  3. Redhat安装Oracle 11g (转)

    1.1     安装前准备 1.1.1     修改操作系统核心参数 在Root用户下执行以下步骤: 1.1.1.1 修改/etc/security/limits.conf文件 输入命令:vi /et ...

  4. SQLServer之修改索引

    使用SSMS数据库管理工具修改索引 使用表设计器修改索引 表设计器可以修改任何类型的索引,修改索引的步骤相同,本示例为修改唯一非聚集索引. 1.连接数据库,选择数据库,选择数据表->右键点击表- ...

  5. LeetCode算法题-Design LinkedList(Java实现)

    这是悦乐书的第300次更新,第319篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第168题(顺位题号是707).设计链表的实现.您可以选择使用单链表或双链表.单链表中的 ...

  6. Git常用命令集锦

    本篇Git命令博客主要是一些Git常用命令,适合于有一定Git或linux基础的小伙伴进行参考 1.新建文件夹 mkdir 文件夹名 2.查看目录机构: pwd 3.将文件添加至Git管理范围:git ...

  7. JavaScript数据类型之null和undeined

    null null是JavaScrpt的关键字,表示一个特殊值,常用于描述"空值".对null执行typeof运算将返回字符串"object". undefin ...

  8. 阿里巴巴开源的Asynchronous I/O Design and Implementation

    Motivation I/O access, for the most case, is a time-consuming process, making the TPS for single ope ...

  9. Configuring Apache Kafka Security

    This topic describes additional steps you can take to ensure the safety and integrity of your data s ...

  10. final等关键字和代码块

    一.final关键字 其作用 1.final除构造方法外均可修饰 2.修饰类:被final修饰的类是无法被继承的. 3.修饰方法,可被继承,但是无法被重写 4.修饰变量使其为常量 5.修饰引用型变量, ...