Java EE之表达式语言EL(上)
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}
。- 关键字
div
和mod
分别对应着/
(除法)和%
(求余),它们只是数学运算符的替代关键字。如果愿意的话,你仍然可以使用/
和%
。 - 关键字
and
、or
和not
分别对应着Java逻辑运算符&&
、||
和!
。 - 关键字
eq
、ne
、lt
、gt
、le
和ge
分别对应着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并未包含char
、byte
和short
类型的字面量,但可以在必要的时候将其他字面量强制转型为char
、byte
和short
。
通过使用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(上)的更多相关文章
- Java EE之表达式语言EL(下)
1.在EL表达式中使用作用域变量 表达式语言对作用域变量的支持,以及它解析变量的方式都使它变得非常有用. 1.1 EL表达式的隐式变量 EL表达式的作用域中定义了11个隐式变量. 当EL表达式引用了一 ...
- 表达式语言EL
表达式语言EL 表达式语言 EL(Expression Language,表达式语言)主要是用在JSP页面中,用来辅助我们产生无脚本的JSP页面,此处的脚本指的是JSP中的Java代码. EL的语法是 ...
- 表达式语言EL简单学习
Jsp2.0最重要的特性就是表达式语言EL.jsp用户可以用它来访问应用程序数据. EL表达式以${开头并以}结束. ${expresion} ${x+y} 它也常用来连接两个表达式,取值将从 ...
- 06.十分钟学会表达式语言EL
一. 概念:MVC设计模式一个主要好处就是让jsp中的代码越来越来少,而且规定只能出现三种代码:接收属性,判断语句,迭代输出.但是,在开发中,jsp输出至少还是需要接受VO对象的,这时候为了避免导入V ...
- 【jsp】详解JSP表达式语言(EL)
一.JSP EL语言定义 E L(Expression Language) 目的:为了使JSP写起来更加简单. 表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 ...
- Java EE之通过表单上传文件
public class Ticket { private String customerName; private String subject; private String body; priv ...
- Java EE Expression Language
什么是EL? 形如这样(立即执行的): ${sessionScope.cart.total} 或者这样(延迟执行的): #{customer.name} 的表达式语言(Expression Langu ...
- Java EE JSP内置对象及表达式语言
一.JSP内置对象 JSP根据Servlet API规范提供了一些内置对象,开发者不用事先声明就可使用标准变量来访问这些对象. JSP提供了9种内置对象: (一).request 简述: JSP编程中 ...
- JSP简明教程(四):EL表达式语言、JavaBean、Cookie、Session
EL表达式语言 EL这是Expression Language.的目的是为了简化JSP句法.来看几个例子来清除. ${test} 它会被翻译成<%=test%> ${test.name} ...
随机推荐
- Linux shell 及命令汇总
1 文件管理命令 1.cat命令:将文件内容连接后传送到标准输出或重定向到文件 2.chmod命令:更改文件的访问权限 3.chown命令:更改文件的所有者 4.find命令:查找(符合条件)文件并将 ...
- 基于tcp的云盘上传下载的模拟
老师的博客: server端 import json import struct import json import struct import socket import os sk = sock ...
- C#基础知识之Dictionary
最近使用了Dictionary,出现了意想不到的错误,先记录一下自己遇到的问题以及目前我的解决方法,然后温习一下Dictionary的基础用法. 一.自己遇到的问题 1.代码如下: namespace ...
- Python爬虫【实战篇】百度贴吧爬取页面存到本地
先上代码 import requests class TiebaSpider: def __init__(self, tieba_name): self.tieba_name = tieba_name ...
- 数据库连接池性能比对(hikari druid c3p0 dbcp jdbc)
https://blog.csdn.net/qq_31125793/article/details/51241943 背景 对现有的数据库连接池做调研对比,综合性能,可靠性,稳定性,扩展性等因素选出推 ...
- react组件之间的通信
通过props传递 共同的数据放在父组件上, 特有的数据放在自己组件内部(state),通过props可以传递一般数据和函数数据, 只能一层一层传递 一般数据-->父组件传递数据给子组件--&g ...
- Generative Adversarial Nets[BEGAN]
本文来自<BEGAN: Boundary Equilibrium Generative Adversarial Networks>,时间线为2017年3月.是google的工作. 作者提出 ...
- Golang 入门系列(四)如何理解interface接口
前面讲了很多Go 语言的基础知识,包括go环境的安装,go语言的语法等,感兴趣的朋友,可以先看看之前的文章.https://www.cnblogs.com/zhangweizhong/category ...
- 开放数据接口 API 简介与使用场景、调用方法
此文章对开放数据接口 API 进行了功能介绍.使用场景介绍以及调用方法的说明,供用户在使用数据接口时参考之用. 在给大家分享的一系列软件开发视频课程中,以及在我们的社区微信群聊天中,都积极地鼓励大家开 ...
- Abp vNext 切换MySql数据库
Abp vNext是Abp的下一代版本,目前还在经一步完善,代码已经全部重写了,好的东西保留了下来,去除了很多笨重的东西,从官宣来看,Abp vNext主要是为了以后微服务架构而诞生的. 从源码来看, ...