EL

EL 全程为 Expression Language 的意思,是在 JSP 中用来代替表达式 <%=Expression%> 的,格式为 ${Expression}

获取并输出数据

获取作用域变量

EL 可以直接将四大作用域的里面设置的属性作为一个变量直接输出,首先设置:

1
2
3
4
5
6
<%
pageContext.setAttribute("Tempest", "Xorex");
request.setAttribute("Yukinoshita", "Yukino");
session.setAttribute("Yuuki", "Ausna");
application.setAttribute("Katou", "Megumi");
%>

然后利用 EL 进行输出:

1
2
3
4
${Tempest}
${Yukinoshita}
${Yuuki}
${Katou}

而 EL 获取数据的实现原理是调用 pageContext.findAttribute(),然后分别按照作用域从小到大从 pageContex、request、session 和 application 作用域中搜索属性对应的名字,如果没有搜索到,会返回一个空串 “” 而不是 null(客户又看不懂 null 的意思,直接为空更好)。

获取 JavaBean 属性

1
2
3
4
5
int ID;
String Name;
short[] scores;
List<String> Address;
Map<String ,String> Love;

我们设置成功之后,需要将这个 JavaBean 对象放到任何一个作用域中(本地变量无效理由如上 EL 实现原理),访问 JavaBean 中的数据使用 .DataName ,这里的访问等价于 .getDataName()。(其实本质上调用的也是 get 方法),其实理论上无论什么类型的类,只要有合乎规范的 getXXX() 方法,在 EL 中就能通过 .XXX 的方式调用这个方法,获取其返回值。(当然上面是有一个比较特殊的存在就是对于 boolean 类型的获取的方法是 isXXX() 但是同样可以使用 .XXX 来进行访问。)

1
${bean.ID} <%-- 这里就等价于输出 bean.getID() --%>

获取 List 元素

List 获取到 List 的对象之后,可以使用 List 自带的 get(int index) 或者使用 [index] 下标来获取某个具体 index 的元素。

下面两者效果相同:

1
2
${bean.address[0]} <br>
${bean.address.get(0)} <br>

获取 Map 元素

下面是一个 JavaBean 的 Map 实例获取映射的方法,下面三种方法完全等效。

1
2
3
${bean.love["Tempest"]} <br>
${bean.love.Tempest} <br>
${bean.love.get("Tempest")} <br>

执行运算

关系运算

看图,输出内容是 boolean 的 true 或 false 的字符串:

逻辑运算

看图,输出内容是 boolean 的 true 或 false :

empty()

判断被传入的对象是否为 null,如果是返回 true 否则返回 false。

表达式运算

传入一个表达式,会自动计算表达式的值,然后输出结果,不解释了。

三元表达式

Expression ? Statement : Statement 可以使用这玩意,不解释了。

EL 中隐含对象

因为 EL 是专门用来代替 <%=Expression%> 的,尤其是处理在四大作用域里面存储的 Map 属性映射。除了我们直接按照作用域范围从小到大去使用 name 值检索其映射的 value 以外,还可以直接获取对应作用域范围里面的隐含 Map 对象来操作:

序号 隐含对象名称 描述
1 pageContext 对应于 JSP 页面中的 pageContext 对象(注意:取的是 pageContext 对象。)
2 pageScope 代表 page 域中用于保存属性的 Map 对象
3 requestScope 代表 request 域中用于保存属性的 Map 对象
4 sessionScope 代表 session 域中用于保存属性的 Map 对象
5 applicationScope 代表 application 域中用于保存属性的 Map 对象
6 param 表示一个保存了所有请求参数的 Map 对象
7 paramValues 表示一个保存了所有请求参数的 Map 对象,它对于某个请求参数,返回的是一个 string[]
8 header 表示一个保存了所有 http 请求头字段的 Map 对象,注意:如果头里面有“-” ,例 Accept-Encoding,则要 header[“Accept-Encoding”]
9 headerValues 表示一个保存了所有 http 请求头字段的 Map 对象,它对于某个请求参数,返回的是一个 string[] 数组。注意:如果头里面有 “-“ ,例 Accept-Encoding,则要 headerValues[“Accept-Encoding”]
10 cookie 表示一个保存了所有 cookie 的 Map 对象
11 initParam 表示一个保存了所有 web 应用初始化参数的 map 对象

使用注意事项

  1. 不可以用上面返回的 Map 对象来向里面改动里面的映射,也就是说,只能读不能写。

  2. 对于获取有特殊字符的键值对映射,不可以使用 .Key-Name ,老老实实 ["Key-Name"] 吧,尤其是在获取请求头的时候,这种情况比较多。

pageContext 对象

这个对象就是 Servlet 里面的 PageContext 的对象,可以获取 JSP 内置的其他八大对象,所以这个东西在 EL 的意义就是获取其他对象来获取大量的页面信息,如:

访问协议、服务器 IP、服务器端口、工程路径、会话 ID、客户端 IP 等等,当中都是借助它保存的其他八大对象来获取的。

1
2
3
${pageContext.request.scheme}
${pageContext.request.serverName}
${pageContext.request.serverPort}

Values 系列

里面获取的 Map 里面提到了有 <String,Stirng[]> 这样映射方式的,就是后缀带 Values 的。主要是为了应对有一个对应多个的映射,比如 checkbox 多选框等等,所以返回一个 String[] 数组方便处理,如果是用 <String,String> 映射的 Map 获取其参数,则默认为第一个元素。

initParam

获取的参数是 web.xml 中的,<context-param> 标签设置的初始化参数。可以用来获取并初始化使用。

JSTL 标签库

JSTL 概述

JSTL 全称为:JSP Standard Tag Library 是用来加强 JSP 中的代码块 <% %> 而诞生的,目的就是希望在 HTML 中不要出现 Java 的逻辑代码。

<c:set>

这个 JSTL 标签的写法就是上面这样其中 c 表示 core 为核心库的意思,set 表示标签的类型,为设置类型。此标签的作用是向作用域中保存数据:

1
<c:set scope="request" var="Tempest" value="Xorex"></c:set>

表示向作用域 request 中写入键值对映射 :"Tempest"->"Xorex"

<c:if>

用于判断 test 属性中填写的表达式返回的 boolean 值,如果为 true ,那么处理此标签包含的内容,如果为 false,则略过标签包含的内容。

1
2
<c:if test="${'Xorex'.equals('Tempest')}">${"Xorex is Tempest!"}</c:if>
${"Xorex is not Tempest!}

<c:choose> <c:when> <c:otherwise>

这个就是为了弥补 <c:if> 里面没有 else 而出现的 switch 语句。最外面必须是 <c:choose> 语句包裹起来,里面则是 <c:when test="BooleanExpression"> 用来处理 test 为 true 的情况(执行处理包裹代码),如果没有 when 处理的话,则会交给 <c:otherwise> 处理。这里面是没有穿透效应的,被 when 处理之后,就退出 choose 标签里面了。

1
2
3
4
5
6
7
8
9
10
11
<c:choose>
<c:when test="${Xorex.waifu==Yukino}">
${"Yukino is my waifu!"}
</c:when>
<c:when test="${Xorex.waifu==Megumi}">
${"Megumi is my waifu!"}
</c:when>
<c:otherwise>
${"Have not this kind of situation."}
</c:otherwise>
</c:choose>

<c:forEach>

用来遍历,是集合 for 和增强 for 的存在。

  • 当作普通循环,begin 和 end 设置枚举范围,var 设置枚举对象名:
1
2
3
<c:forEach begin="0" end="10" var="i">
${i}
</c:forEach>
  • 当作增强循环,在 itens 中输入实现了迭代器的对象,然后 var 设置单个遍历出来的变量名。
1
2
3
<c:forEach items="${array}" var="waifu">
${waifu} <br>
</c:forEach>
  • 遍历 Map ,首先用 map 对象的 entrySet() 方法返回一个 EntrySet 对象,然后用增强循环遍历这个 Set,并获取每个 map 里保存的 key 和 value。
1
2
3
<c:forEach items="${map.entrySet()}" var="entry">
${entry.key} ${entry.value} <br>
</c:forEach>

这里有一个值得说一说的 varStatus 属性,给他设置一个变量名之后,便可以通过这个变量名访问这个对象,它里面记录了本次循环的各种信息,可以供我们参考: