JavaWeb——EL表达式、JSTL标签
目录
1.前言
在 JavaWeb 开发模式中,JSP 作为界面用于实现输入和输出。输入是通过表单实现的,输出是通过 JSP 的内置对象 out 或表达式实现的。被输出的数据通常存储到四个作用域中,而向界面输出数据通常使用 EL 和 JSTL 实现。使用 EL 可以代替,使用 JSTL 可以代替 java 语言中的定义变量、if 语句等,实现在界面上不出现 Java 代码,只有标签,使得前端开发人员与后端开发人员高效协同开发软件。
2.EL表达式
EL 表达式又称为表达式语言(Expression Language),它是 JSP 中一个很重要的组成部分。在 JSP 页面中使用 EL 表达式,可以简化对变量和对象的访问。
EL 表达式的语法非常的简单,所有的 EL 表达式都是以“${”开始,以“}”结束,比如
${name}。EL 表达式会将表达式中的结果在页面上输出,就像使用 JSP 的表达式结构或使用out 内置对象进行输出一样。
2.1 EL 表达式对运算符支持
使用 EL 表达式支持算术运算,包括+、-、*、/、%。在 eljstl 项目中添加一个 jsp 文件,
命名为 el1.jsp,el1.jsp 代码编写如下
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>EL 表达式算术运算</title> </head> <body> 12 + 15 = ${12+15} <br> 12 * 15 = ${12*15} <br> 12 - 15 = ${12-15} <br> 12 / 15 = ${12/15} <br> 12 % 15 = ${12%15}<br> </body> </html>
在 EL 表达式中还可以支持关系运算符操作。在 eljstl 项目中添加一个 jsp 文件,命名为
el2.jsp,el2.jsp 代码编写如下
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>EL 表达式关系运算符</title> </head> <body> 12==15 ${12==15} <br> 12<15 ${12<15} <br> 12>15 ${12>15} <br> 12<=15 ${12<=15} <br> 12>=15 ${12>=15} <br> 12!=15 ${12!=15} </body> </html>
EL 表达式中同样支持逻辑运算,在 eljstl 项目中添加一个 jsp 文件,命名为 el4.jsp,
el4.jsp 代码编写如下
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>EL 表达式逻辑运算 </title> </head> <body> 12 < 15 && 12 < 15 ${12 < 15 && 12 < 15 }<br> 12 < 15 and 12 < 15 ${12 < 15 and 12 < 15 }<br> 12 < 15 || 12 > 15 ${12 < 15 || 12 > 15 }<br> 12 < 15 or 12 >15 ${12 < 15 or 12 >15 }<br> !(12 < 15) ${!(12 < 15) }<br> not (12 < 15)${not (12 < 15) } </body> </html>
可以看出 EL 表达式中不仅支持&&、||、!方式的逻辑运算符,同样也支持 and、or、not
方式的逻辑运算符。在 EL 表达式中也可以小括号来提升运算符的优先级。
EL 表达式中还可以使用 empty 运算符检测一个值是否为 null 或者为空。在 eljstl 项目
中添加一个 jsp 文件,命名为 el5.jsp,el5.jsp 代码编写如下
<%@page import="java.util.ArrayList"%> <%@page import="java.util.List"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>EL 表达式 empty 运算符</title> </head> <body> <% List list = new ArrayList(); list.add("tom"); pageContext.setAttribute("str", null); pageContext.setAttribute("list", list); %> empty str = ${empty str }<br /> empty list = ${empty list} </body> </html>
- empty str 判断内容是否为 null
- empty list 判断集合 list 中是否有元素
EL 表达式中还支持三元表达式方式的条件选择运算。在 eljstl 项目中添加一个 jsp 文
件,命名为 el6.jsp,el6.jsp 代码编写如下
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>EL 三元表达式</title> </head> <body> 12 < 15 ? 'yes':'no' = ${12 < 15 ? 'yes':'no' } </body> </html>
注意在 EL 表达式中的字符串需要使用单引号引起来。
2.2 EL 访问对象
EL 表达式的方便性不仅仅体现在对这些算术或关系运算的支持,它还可以很方便的访问对象。例如任务 5 中讲 empty 运算符时,使用 EL 表达式可以访问 page 作用域中的对象。在 JavaWeb 开发中,EL 表达式的多数应用场景是首先将要显示的数据存储在某一个作用域中,然后使用 EL 表达式将作用域中的数据显示在界面上。
在 eljstl 项目中添加一个 jsp 文件,命名为 el7.jsp,el7.jsp 代码编写如下
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>EL 表达式访问对象</title> </head> <body> <% pageContext.setAttribute("name", "林冲"); request.setAttribute("age", "22"); session.setAttribute("address", "中国"); application.setAttribute("score", "75.5"); %> name=${name}<br> age=${age}<br> address=${address}<br> score=${score}<br> </body> </html>
EL 访问对象只需要在 EL 表达式中写对象的名称即可。EL 表达
式默认会从 page、request、session、application 作用域中按照从小到大的顺序寻找名称匹配的对象,如果找到了,则显示找到的对象,如果找不到,则不显示任何内容。还可以指定从哪个范围中获取对象。
在 eljstl 项目中添加一个 jsp 文件,命名为 el8.jsp,el8.jsp 代码编写如下
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>EL 表达式从指定范围内访问对象</title> </head> <body> <% pageContext.setAttribute("name","林冲"); request.setAttribute("age","22"); session.setAttribute("address","中国"); application.setAttribute("score","75.5"); %> name = ${pageScope.name}<br>age = ${requestScope.age}<br>address = ${sessionScope.address}<br>score = ${applicationScope.score}<br> </body> </html>
- pageScope 代表 page 范围的作用域。
- requestScope 代表 request 范围的作用域。
- sessionScope 代表 session 范围的作用域。
- applicationScope 代表 application 范围的作用域。
作用域与范围的对应关系如表 2 所示,在 EL 表达式中指定了作用域,那么 EL 表达式就显示指定作用域中的数据,如果指定作用域中不存在要显示的数据,则 EL 表达式不输出任何内容。
2.3 EL 显示对象
第一步:自定义类
在 eljstl 项目的 src 包中添加一个类,命名为 User,在 User 类中定义 name 和
address 私有属性,为 name 和 address 私有属性设置公有的 getter/setter 方法,代码如
下:
public class User { private String name; private String address; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return name + "来自" + address; } }
第二步:创建 jsp 文件
在 eljstl 项目中添加一个 jsp 文件,命名为 el9.jsp,el9.jsp 代码编写如下
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>EL 显示对象</title> </head> <body> <% cn.itlaobing.User user = new cn.itlaobing.User(); user.setName("林冲"); user.setAddress("西安"); pageContext.setAttribute("user1", user); %> ${user1} </body> </html>
代码解析
- pageContext.setAttribute(“user1”, user)实现将 user 对象存储到键为 user1 的 page 作用域中。
- ${user1}表示显示键 user1 中存储的对象 user,默认显示 user 对象的 toString()方法的返回值。
还可以使用 EL 表达式显示作用域中某个对象的属性值。在 eljstl 项目中添加一个 jsp 文件,命名为 el10.jsp,el10.jsp 代码编写如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>EL 显示对象的属性</title> </head> <body> <% cn.itlaobing.User user = new cn.itlaobing.User(); user.setName("林冲"); user.setAddress("西安"); pageContext.setAttribute("user1", user); %> name = ${user1.name}<br> address = ${user1.address} </body> </html>
代码解析
- 在 EL 表达式中通过点“.”运算符来获取对象属性的值,如本例中${user1.name}。
- 特别提醒${user1.name}中的 name 并不是 User 类的属性名 name,而是 name 属性对应的 get 方法的方法名去掉 get 后的单词首字母变小写的结果,如图 10 所示。
3. JSTL 核心标签库
JSTL 全称为(JavaServer Page Standard Tag Library 即:JSP 标准标签库),是由 SUN 公司提供的简化 JSP 页面设计的标签。JSTL 是由 Core、I18N、SQL、XML、Functions 五个核心标签库组成,其中常用的是 Core 标签库和 I18N 标签库中的格式化标签库。Core 标签库中包含了基本标签、条件标签、迭代标签。JSTL 和 EL 表达式通常会一起使用。 在使用 JSTL 之前需要先下载包含 JSTL 的 jar 包,JSTL 的 Jar 包由 jstl.jar 和 standard.jar 组
成,下载的网址为 http://jakarta.apache.org/site/downloads/downloads_taglibs-standard.cgi。
使用 JSTL 需要三个步骤
- 将 JSTL 所需的 jstl.jar 和 standard.jar 拷贝到项目的 WEB-INF/lib 目录下
- 在 JSP 页面中使用 taglib 指令导入标签库
- 在 JSP 页面中使用标签
3.1 标签
标签用于在四大作用域中声明变量并赋值,它的属性如表 3 所示。
3.2 标签
标签用于将作用域内的变量进行显示输出。
属性名 | 描述 |
---|---|
value | 输出值的变量名 |
escapeXml | 确定在结果字符串中的字符“ ’ " & ”等符号应该被转换为对应的字符引用或预定义实体引用,默认值为 true |
default | 如果 value 为 null,则显示 default 中的值 |
target | 用来获得一个引用 |
var | 用来声明一个变量 |
3.3 标签
标签用于将变量从作用域内移除。
属性名 | 描述 |
---|---|
var | 要移除的变量名称 |
scope | var 的范围名称,默认为 page |
3.4 基本标签的使用
在 eljstl 项目中添加一个 jsp 文件,命名为 jstl1.jsp,jstl1.jsp 代码编写如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body><c:set var="name" value="林冲" scope="session"/><c:set var="age" scope="page">22</c:set><c:set var="code" value="hello"/> <c:out value="${name}"/> <br/><c:out value="${age}"/><br/><c:out value="${address}" default="地址不详"/><br/><c:out value="${code}"/><br/><c:out value="${code}" escapeXml="false"/><c:remove var="name" scope="session"/> </body> </html>
代码解析
- 导入了 JSP 标准标签库,其中 uri 是标签库的唯一标识;prefix 是标签的前缀,由开发人员自定义。
- 使用 set 标签定义了三个变量 name,age,code,var 用于定义变量名,value 为变量赋值,scope 设置变量存储在哪个作用域中,默认是 page 作用域。
- out 标签的 value 是向页面输出的数据,被输出的数据使用 EL 表达式获取,如果 out 标签设置了 default,表示 EL 表达式没有在作用域中获取到数据时,在界面上显示 default的值。
- escapeXml 表示被输出数据中的标签是否需要转义,若其值为 false 表示将标签直接显示在界面上,若其值为 true 表示将标签解释后的结果显示在界面上。
- remove 标签用于将某个作用域中的数据移除,默认移除 page 作用域中的数据。
3.5 标签
标签的作用和 Java 语言中的 if 语句功能是相同的。
Core 标签库标签
在 eljstl 项目中添加一个 jsp 文件,命名为 jstl2.jsp,jstl2.jsp 代码编写如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <c:if test="${12 > 10}" var="result" scope="page">12 大于 10 test 的结果为${result } </c:if> <c:if test="${12 < 10}">12 小于 10 </c:if> </body> </html>
代码解析
- if 标签实现判断功能,相当于 Java 语言中的 if 语句。
- if 标签使用 test 属性判断条件是否成立,如果条件成立,则执行和之间的代码。
- 如果 test 条件成立,将判断条件的返回值存储到 scope 指定的作用域中,scope 是可选项,其默认值是 page。存储在作用域中的数据的键由 var 属性指定。
- 本例实现了将 12>10 的判断结果,存储到键为 result 的 page 作用域中。
3.6 和标签
、和一起实现 Java 语言中的 if/else 功能。标签是和标签的父标签,在标签中只能出现这两个子标签。
Core 标签库标签
在 eljstl 项目中添加一个 jsp 文件,命名为 jstl3.jsp,jstl3.jsp 代码编写如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <c:set var="name" value="李逵"></c:set> <c:choose> <c:when test="${name eq '林冲'}"> 林冲 </c:when> <c:when test="${name eq '李逵'}"> 李逵</c:when> <c:otherwise> 姓名未知</c:otherwise> </c:choose> </body> </html> </html>
- 如果标签 test 条件返回值 true,该标签体则会执行。
- 如果标签中的标签都不成立,则执行标签体。
3.7 标签
标签为 Core 标签库中的迭代标签,主要属性有:
forEach 迭代数组和集合
在 eljstl 项目中添加一个 jsp 文件,命名为 jstl4.jsp,jstl4.jsp 代码编写如下:
<%@page import="java.util.*"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <% Map<String, String> map = new HashMap<String, String>(); map.put("key1", "宋江"); map.put("key2", "燕青"); map.put("key3", "李逵"); List<String> list = new ArrayList<String>(); list.add("林冲"); list.add("史进"); list.add("鲁智深"); String[] strs = { "孙二娘", "扈三娘", "顾大嫂" }; request.setAttribute("list", list); request.setAttribute("strs", strs); request.setAttribute("map", map); %> <body> 对数组的迭代: <br /> <c:forEach var="str" items="${strs}" varStatus="status"> ${status.count} ${str}<br /> </c:forEach> 对 List 集合的迭代: <br /> <c:forEach var="listItem" items="${list}" begin="0" end="1"> ${listItem}<br /> </c:forEach> 对 Map 集合的迭代: <br /> <c:forEach var="mapItem" items="${map}"> ${mapItem.key} : ${mapItem.value}<br /> </c:forEach> </body> </html> </html>
代码解析
- 数组或集合中有多少个对象,forEach 就自动循环多少次,每次自动迭代出一个对象。
- forEach 迭代时,items 属性用于设置被迭代的集合或数组,var 属性用于设置当前被迭代的对象。
- 迭代数组时,将数组中每个元素存储到 str 变量中并在迭代体中输出。在 varStatus属性中声明迭代状态对象 status。status 对象是javax.servlet.jsp.jstl.core.LoopTagStatus接口的对象,在该接口中还定义了 getIndex()、getCount()、getFrist()、getLast()四个方法,分别代表当前元素的索引、当前元素是第几个元素、当前元素是否为第一个元素、当前元素是否为最后一个元素,在使用时需要去掉 get,并将 get 后面的字母小写。
- 迭代 List 集合时,begin 属性指定了迭代的开始索引,end 属性指定迭代的结束索引。
- 迭代 map 集合时,调用 map 集合中元素的 key 和 value 属性可以获得该元素的 key值及 value 值。
4. JSTL 格式化标签库
格式化标签库中包含了对数字,日期的格式化标签。在使用 JSTL 格式化标签库时,需要在使用的 JSP 页面中使用 taglib 指令导入格式化标签:
在 JSTL 格式化标签中最常用的是fmt:formatNumber标签和fmt:formatDate标签,分别代表对数字和日期的格式化输出。
4.1
格式化标签
在 eljstl 项目中添加一个 jsp 文件,命名为 jstl5.jsp,jstl5.jsp 代码编写如下:
<%@page import="java.util.*"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>格式化标签</title> </head> <body> 格式化货币: <fmt:formatNumber value="7898712.567878" type="currency" currencySymbol="$" maxFractionDigits="3" /><br /> 格式化数字: <fmt:formatNumber value="123456.1" type="number" minFractionDigits="3" /><br /> 格式化百分比: <fmt:formatNumber type="percent"> 0.98 </fmt:formatNumber> </body> </html> </html>
代码解析
- formatNumber 标签用于格式化数字。
- 当 type="currency"时,将 value 中的值格式为美元货币格式,小数部分最大位数为 3 位。
- 当 type="number"时,将 value 中的值格式化为数字格式,小数部分最小位数为 3 位,不足 3 位使用 0 补齐。
- 当 type="percent"时,将标签体内的值格式化为百分比格式。“percent"仅用在 Apache JSTL中,其他容器提供的 JSTL 要写作"percentage”。
4.2
格式化标签
在 eljstl 项目中添加一个 jsp 文件,命名为 jstl6.jsp,jstl6.jsp 代码编写如下:
<%@page import="java.util.*"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>格式化标签</title> </head> <body> <fmt:formatDate value="" pattern="yyyy 年 MM 月 dd 日"/><br/> <fmt:formatDate value="" dateStyle="full"/><br/> <fmt:formatDate value="" type="time"/> </body> </html> </html>
代码解析
- formatDate 标签用于格式化日期
- value 属性的值时被格式化的日期
- pattern 属性设置日期格式,yyyy 表示 4 位的年份,MM 表示 2 位的月份,dd 表示 2位的日期。
- dateStyle 是日期的预定义格式化样式。
- type 设置显示的是日期,或者时间,或者日期和时间。
4.3 fn:contains()函数
fn:contains()函数用于确定一个字符串是否包含指定的子串。
语法:
fn:contains()函数的语法如下:
<c:if test="${fn:contains(, )}"> ... </c:if>
实例演示:
以下实例演示了这个函数的功能:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> <html> <head> <title>使用 JSTL 函数</title> </head> <body> <c:set var="theString" value="I am from 123456.org"/> <c:if test="${fn:contains(theString, '123456')}"> <p>找到 123456<p> </c:if> <c:if test="${fn:containsIgnoreCase (theString, '123456')}"> <p>找到 123456s<p> </c:if> </body> </html>