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. Linux shell 及命令汇总

    1 文件管理命令 1.cat命令:将文件内容连接后传送到标准输出或重定向到文件 2.chmod命令:更改文件的访问权限 3.chown命令:更改文件的所有者 4.find命令:查找(符合条件)文件并将 ...

  2. 基于tcp的云盘上传下载的模拟

    老师的博客: server端 import json import struct import json import struct import socket import os sk = sock ...

  3. C#基础知识之Dictionary

    最近使用了Dictionary,出现了意想不到的错误,先记录一下自己遇到的问题以及目前我的解决方法,然后温习一下Dictionary的基础用法. 一.自己遇到的问题 1.代码如下: namespace ...

  4. Python爬虫【实战篇】百度贴吧爬取页面存到本地

    先上代码 import requests class TiebaSpider: def __init__(self, tieba_name): self.tieba_name = tieba_name ...

  5. 数据库连接池性能比对(hikari druid c3p0 dbcp jdbc)

    https://blog.csdn.net/qq_31125793/article/details/51241943 背景 对现有的数据库连接池做调研对比,综合性能,可靠性,稳定性,扩展性等因素选出推 ...

  6. react组件之间的通信

    通过props传递 共同的数据放在父组件上, 特有的数据放在自己组件内部(state),通过props可以传递一般数据和函数数据, 只能一层一层传递 一般数据-->父组件传递数据给子组件--&g ...

  7. Generative Adversarial Nets[BEGAN]

    本文来自<BEGAN: Boundary Equilibrium Generative Adversarial Networks>,时间线为2017年3月.是google的工作. 作者提出 ...

  8. Golang 入门系列(四)如何理解interface接口

    前面讲了很多Go 语言的基础知识,包括go环境的安装,go语言的语法等,感兴趣的朋友,可以先看看之前的文章.https://www.cnblogs.com/zhangweizhong/category ...

  9. 开放数据接口 API 简介与使用场景、调用方法

    此文章对开放数据接口 API 进行了功能介绍.使用场景介绍以及调用方法的说明,供用户在使用数据接口时参考之用. 在给大家分享的一系列软件开发视频课程中,以及在我们的社区微信群聊天中,都积极地鼓励大家开 ...

  10. Abp vNext 切换MySql数据库

    Abp vNext是Abp的下一代版本,目前还在经一步完善,代码已经全部重写了,好的东西保留了下来,去除了很多笨重的东西,从官宣来看,Abp vNext主要是为了以后微服务架构而诞生的. 从源码来看, ...