菜鸟教程:https://www.runoob.com/jsp/jsp-jstl.html
易百教程:https://www.yiibai.com/jsp/jstl.html
一、EL
(一)为什么需要EL
1)在JSP中使用Java脚本的局限
- 在JSP页面中嵌入大量的Java代码
- 访问结构比较复杂的数据时代码烦琐,且经常需要强制类型转换
<% Employee employee = (Employee) request.getAttribute("employee"); Computer comp = employee.getComputer(); String manufacturer = comp.getManufacturer(); %>
2)EL表达式使JSP的开发变得更加简单
(二)EL表达式简介
1)什么是EL
- Expression Language(表达式语言)
2)EL的功能
- 替代JSP页面中数据访问时的复杂编码
3)EL的特点
- 自动转换类型 —— EL得到某个数据时可以自动转换类型
- 使用简单
- 在JSP EL表达式内可以使用整型数,浮点数,字符串,常量,true、false,还有null。
(三)EL表达式语法
${ ELexpression }
ELexpression 指的是表达式。在JSP EL中通用的操作符是 . 和 {} 。这两个操作符允许您通过内嵌的JSP对象访问各种各样的JavaBean属性。
- 通过变量名取值
- 获取对象的属性值
- 获取集合元素
- 执行表达式
1)${变量名}
- 按照page → request → session → application的作用域顺序依次查找,找到即返回,最终找不到返回null
// 在Servlet或JSP中保存数据
request.setAttribute("username", "LiYang");
// 在JSP中访问数据
姓名: ${username}//==> ${requestScope.username}
- 指定作用域
属性范围 | EL中的名称 |
page | pageScope,例如${pageScope.username}表示在page作用域查找变量username,找不到返回null |
request | requestScope |
session | sessionScope |
application | applicationScope |
- JSP EL隐含对象
JSP EL支持下表列出的隐含对象:
https://www.runoob.com/jsp/jsp-expression-language.html
隐含对象 | 描述 |
---|---|
pageScope | page 作用域 |
requestScope | request 作用域 |
sessionScope | session 作用域 |
applicationScope | application 作用域 |
param | Request 对象的参数,字符串 |
paramValues | Request对象的参数,字符串集合 |
header | HTTP 信息头,字符串 |
headerValues | HTTP 信息头,字符串集合 |
initParam | 上下文初始化参数 |
cookie | Cookie值 |
pageContext | 当前页面的pageContext |
2)获取对象的属性值
<%= ( (User) request.getAttribute("user") ) .getName() %>
- 点操作符(访问一个Bean属性或者一个映射条目) —— ${user.name}
- [ ]操作符(访问一个数组或者链表的元素) —— ${user["name"]}
需要回忆
jsp中<%%>是如何获取request当中的属性值
JavaBean中需要有相应getter方法才能用EL表达式这样取值。
${user[“name”]}中的name如果不加引号,则表示名为name的变量,可以实现对user属性的动态访问
- EL中的基础操作符
操作符 | 描述 |
---|---|
. | 访问一个Bean属性或者一个映射条目 |
[] | 访问一个数组或者链表的元素 |
( ) | 组织一个子表达式以改变优先级 |
+ | 加 |
- | 减或负 |
* | 乘 |
/ or div | 除 |
% or mod | 取模 |
== or eq | 测试是否相等 |
!= or ne | 测试是否不等 |
< or lt | 测试是否小于 |
> or gt | 测试是否大于 |
<= or le | 测试是否小于等于 |
>= or ge | 测试是否大于等于 |
&& or and | 测试逻辑与 |
|| or or | 测试逻辑或 |
! or not | 测试取反 |
empty | 测试是否空值 |
3)获取集合元素-List
// 在Servlet或JSP中保存数据
List names = new ArrayList();
names.add(0, "LiYang");
names.add(1,"WangHua");
request.setAttribute("names",names);
// 在JSP中访问数据 使用[ ]指定元素下标
姓名:${ names[0] }<br/>
姓名:${ names[1] }<br/>
4)获取集合元素-Map
// 在Servlet或JSP中保存数据
Map names = new HashMap();
names.put("one", "LiYang");
names.put("two", "WangHua");
request.setAttribute("names", names);
// 在JSP中访问数据
姓名:${ names.one }<br/>
姓名:${ names["two"] }<br/>
1、Map建议使用String做key,如果使用纯数值格式则只能使用长整形
Map names = new HashMap();
names.put(1L, "LiYang");
names.put("two", "WangHua");
request.setAttribute("names", names);
2、对于String类型的key,${names["two"]}和${names.two}均可,对于Long类型的key仅可使用${names[1]}
5)执行表达式
- 关系操作符
- 逻辑操作符
- empty操作符
关系操作符 (重点为关系操作符,常用的是等于和不等于,注意empty操作符的使用)
关系操作符 | 说明 | 示例 | 结果 |
==(或eq) | 等于 | ${23==5}或${23 eq 5} ${"a" =="a"}或${"a" eq "a"} | false true |
!=(或ne) | 不等于 | ${23!=5}或${23 ne 5} | true |
<(或lt) | 小于 | ${23<5}或${23 lt 5} | false |
>(或gt) | 大于 | ${23>5}或${23 gt 5} | true |
<=(或le) | 小于等于 | ${23<=5}或${23 le 5} | false |
>=(或ge) | 大于等于 | ${23>=5}或${23 ge 5} | ture |
逻辑操作符
逻辑操作符 | 说明 | 示例 | 结果 |
&&(或and) | 逻辑与 | 如果A为true,B为false,则${ A && B } (或${ A and B } ) | false |
||(或or) | 逻辑或 | 如果A为true,B为false,则${ A || B} (或 ${ A or B } ) | true |
! (或not) | 逻辑非 | 如果A为true,则${ ! A } ( 或${ not A } ) | false |
empty操作符
若变量 a为null,或长度为零的String,或size为零的集合
则${ empty a }返回的结果为true
${ not empty a }或${ ! empty a }返回的结果为false
(四)EL隐式对象
1、EL隐式对象介绍
对象名称 | 说 明 |
pageScope | 与page作用域相关联的Map对象 |
requestScope | 与request作用域相关联的Map对象 |
sessionScope | 与session作用域相关联的Map对象 |
applicationScope | 与application作用域相关联的Map对象 |
param | 按照请求参数名称返回单一值的Map对象 |
paramValues | 按照请求参数名称返回String数组的Map对象 |
pageContext | 提供对页面信息和JSP内置对象的访问 |
(五)JSP EL中的函数
JSP EL允许您在表达式中使用函数。这些函数必须被定义在自定义标签库中。函数的使用语法如下:
${ns:func(param1, param2, ...)}
ns指的是命名空间(namespace),func指的是函数的名称,param1指的是第一个参数,param2指的是第二个参数,以此类推。比如,有函数fn:length,在JSTL库中定义,可以像下面这样来获取一个字符串的长度:
${fn:length("Get my length")}
1.语法
- 添加taglib指令
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
- fn:substring(string, begin, end)
返回参数string部分字符串, 从参数begin开始到参数end位置,包括end位置的字符
- fn:length(item)
返回参数item的长度
<c:if test="${fn:length(msg.content) > 8}">
<c:out value="${fn:substring(msg.content,0,7)}"/>....
</c:if>
<c:if test="${fn:length(msg.content) <= 8}">
<c:out value="${msg.content}"/>
</c:if>
二、JSTL
(一)为什么使用JSTL
问:使用EL表达式可以简化JSP页面编码,但是如果需要进行逻辑判断和循环控制怎么办?
EL表达式封装了数据访问的功能,而JSTL标签库则封装了逻辑控制、循环控制以及数据格式化等功能,二者结合使用才能完整实现动态页面的开发需求
(二)jstl概念
1.什么是JSTL
- JSP标准标签库(JSP Standard Tag Library)
- JSTL是一个JSP标签集合,它封装了JSP应用的通用核心功能。
- JSTL支持通用的、结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。 它还提供了一个框架来使用集成JSTL的自定义标签。
- JSTL通常会与EL表达式合作实现JSP页面的编码
2.JSTL的优点
- 提供一组标准标签
- 可用于编写各种动态 功能
(三)JSTL的环境搭建
1.使用JSTL的步骤
- 引入JSTL的jar文件和标签库描述符文件
- 在JSP页面添加taglib指令
- 使用JSTL标签
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
2.JSTL标准标签库介绍
3.通用标签
1)set:设置指定范围内的变量值(用于保存数据//用于设置变量值和对象属性。)
- 将value值存储到范围为scope的变量variable中
<c:set var="variable" value="value" scope="scope" />
- 将value值设置到对象的属性中
<c:set target="target" property="property" value="value" />
- 属性
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
value | 要存储的值 | 否 | 主体的内容 |
target | 要修改的属性所属的对象 | 否 | 无 |
property | 要修改的属性 | 否 | 无 |
var | 存储信息的变量 | 否 | 无 |
scope | var属性的作用域 | 否 | Page |
- 如果指定了target属性,那么property属性也需要被指定。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>c:set 标签实例</title>
</head>
<body>
<c:set var="salary" scope="session" value="${2000*2}"/>
<c:out value="${salary}"/>
</body>
</html>
运行结果如下:
4000
--菜鸟教程
// 在Servlet或JSP中设置JavaBean
User user = new User();
request.setAttribute("user", user);
// 在JSP中修改JavaBean的属性值
<c:set target="${user}" property="name" value="defaultName" />
2)out:计算表达式并将结果输出显示(用于在JSP中显示数据,就像<%= ... >)
- 不指定默认值
<c:out value="value" />
- 指定默认值
<c:out value="value" default="default" />
// 在Servlet或JSP中设置JavaBean
User user = new User();
request.setAttribute("user", user);
// 在JSP中输出JavaBean的属性值
<c:out value="${user.name}" default="No UserName" />
- 属性
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
value | 要输出的内容 | 是 | 无 |
default | 输出的默认值 | 否 | 主体中的内容 |
escapeXml | 是否忽略XML特殊字符 | 否 | true |
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>c:out 标签实例</title>
</head>
<body>
<h1><c:out> 实例</h1>
<c:out value="<要显示的数据对象(未使用转义字符)>" escapeXml="true" default="默认值"></c:out><br/>
<c:out value="<要显示的数据对象(使用转义字符)>" escapeXml="false" default="默认值"></c:out><br/>
<c:out value="${null}" escapeXml="false">使用的表达式结果为null,则输出该默认值</c:out><br/>
</body>
</html>
运行结果如下:
<c:out> 实例
<要显示的数据对象(未使用转义字符)>
<要显示的数据对象(使用转义字符)>
使用的表达式结果为null,则输出该默认值
原文出自【菜鸟教程】
- 转义特殊字符
<p>${ "<a href='http://www.baidu.com'>百度</a>" }</p>
<p> <c:out escapeXml="false" value="<a href='http://www.baidu.com'>百度</a>" /> </p>
<c:out value="<a href='http://www.baidu.com'>百度</a>" />
3)remove:删除指定范围内的变量(用于删除数据)
<c:remove var="variable" scope="scope" />
- <c:remove>标签有如下属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
var | 要移除的变量名称 | 是 | 无 |
scope | 变量所属的作用域 | 否 | 所有作用域 |
<!-- 设置之前应该是空值 -->
设置变量之前的值是:msg=<c:out value="${msg}" default="null" /><br/>
<!-- 给变量msg设值 -->
<c:set var="msg" value="Hello World!" scope="page"></c:set>
<!-- 此时msg的值应该是上面设置的“Hello World!” -->
设置新值以后:msg=<c:out value="${msg}"></c:out><br/>
<!-- 把msg变量从page范围内移除-->
<c:remove var="msg" scope="page" />
<!-- 此时msg的值应该显示null -->
移除变量msg以后:msg=<c:out value="${msg}"></c:out>
输出结果:
设置变量之前的值是:msg=null
设置新值以后:msg=Hello World!
移除变量msg以后:msg=
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>c:remove 标签实例</title>
</head>
<body>
<c:set var="salary" scope="session" value="${2000*2}"/>
<p>salary 变量值: <c:out value="${salary}"/></p>
<c:remove var="salary"/>
<p>删除 salary 变量后的值: <c:out value="${salary}"/></p>
</body>
</html>
运行结果如下:
salary 变量值: 4000
删除 salary 变量后的值:
--菜鸟教程
4)通用标签的使用
<!--引入使用核心标签的指令-->
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!--set标签用于给变量设置值和作用范围,scope="page|request|session|application"-->
<c:set var="example" value="${100+1}" scope="session" />
<!--out 标签在页面上显示信息或变量值-->
<c:out value="${example}"/>
<!--remove 标签用于删除作用域内的变量-->
<c:remove var="example" scope="session"/>
</body>
4.条件标签
1)if:实现Java语言中if语句的功能
<c:if test="条件" var="用于存储条件结果的变量" scope="var属性的作用域" >
…
</c:if>
test="codition" 判断条件表达式 返回true/false
var="variable" 该变量用于保存 返回的true/false
scope="scope" 指定var变量的作用域
- <c:if>标签有如下属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
test | 条件 | 是 | 无 |
var | 用于存储条件结果的变量 | 否 | 无 |
scope | var属性的作用域 | 否 | page |
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>c:if 标签实例</title>
</head>
<body>
<c:set var="salary" scope="session" value="${2000*2}"/>
<c:if test="${salary > 2000}">
<p>我的工资为: <c:out value="${salary}"/><p>
</c:if>
</body>
</html>
运行结果如下:
我的工资为: 4000
--菜鸟教程
- 使用if标签判断是否登录
<c:set var="isLogin" value="${empty sessionScope.user}"/>
<c:if test="${isLogin}">
…登录表单
</c:if>
<c:if test="${! isLogin}">
…已经登录
</c:if>
2)choose:实现if - else if - else语句的功能
- <c:choose>, <c:when>, <c:otherwise> 标签
<c:choose>
<c:when test="condition1">
内容1
</c:when>
<c:when test="condition2">
内容2
</c:when>
……
<c:otherwise>
内容n
</c:otherwise>
</c:choose >
属性
- <c:choose>标签没有属性。
- <c:when>标签只有一个属性。
- <c:otherwise>标签没有属性。
<c:when>标签的属性如下:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
test | 条件 | 是 | 无 |
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>c:choose 标签实例</title>
</head>
<body>
<c:set var="salary" scope="session" value="${2000*2}"/>
<p>你的工资为 : <c:out value="${salary}"/></p>
<c:choose>
<c:when test="${salary <= 0}">
太惨了。
</c:when>
<c:when test="${salary > 1000}">
不错的薪水,还能生活。
</c:when>
<c:otherwise>
什么都没有。
</c:otherwise>
</c:choose>
</body>
</html>
运行结果如下:
你的工资为 : 4000
不错的薪水,还能生活。
--菜鸟教程
5.迭代标签
1)forEach:实现对集合对象的遍历
- <c:forEach>标签是更加通用的标签,因为它迭代一个集合中的对象。
- <c:forTokens>标签通过指定分隔符将字符串分隔为一个数组然后迭代它们。
<c:forEach items="collection" var="varName" begin="start" end="end" step="stepSize" varStatus="status" >
…循环体代码…
</c:forEach>
items指定要遍历的集合对象
var指定当前成员的引用
begin指定从集合的第几位开始
end指定迭代到集合的第几位结束
step指定循环的步长
varStatus属性用于存放var引用的成员的相关信息,如索引等
- <c:forEach>标签有如下属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
items | 要被循环的信息 | 否 | 无 |
begin | 开始的元素(0=第一个元素,1=第二个元素) | 否 | 0 |
end | 最后一个元素(0=第一个元素,1=第二个元素) | 否 | Last element |
step | 每一次迭代的步长 | 否 | 1 |
var | 代表当前条目的变量名称 | 否 | 无 |
varStatus | 代表循环状态的变量名称 | 否 | 无 |
- <c:forTokens>标签与<c:forEach>标签有相似的属性,不过<c:forTokens>还有另一个属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
delims | 分隔符 | 是 | 无 |
<c:forEach>实例演示
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>c:forEach 标签实例</title>
</head>
<body>
<c:forEach var="i" begin="1" end="5">
Item <c:out value="${i}"/><p>
</c:forEach>
</body>
</html>
运行结果如下:
Item 1
Item 2
Item 3
Item 4
Item 5
<c:forTokens>演示实例
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>c:forTokens 标签实例</title>
</head>
<body>
<c:forTokens items="google,runoob,taobao" delims="," var="name">
<c:out value="${name}"/><p>
</c:forTokens>
</body>
</html>
运行结果如下:
google
runoob
taobao
--菜鸟教程
- 通过迭代标签显示商品列表
// 在Servlet或JSP中准备集合数据
List products = GoodsDao.getAllProducts();
request.setAttribute("products", products);
// 在JSP中展示数据
<!-- 循环输出商品信息 -->
<c:forEach items="${requestScope.products}" var="product" varStatus="status">
<!-- 如果是偶数行,为该行换背景颜色 -->
<tr <c:if test="${status.index % 2 == 1 }">
style="background-color:rgb(219,241,212);"</c:if>
>
<td>${product.name }</td>
<td>${product.area }</td>
<td>${product.price }</td>
</tr>
</c:forEach>
2)通过迭代标签遍历Map
// 在Servlet或JSP中准备数据
Map<String, String> map = new HashMap<String, String>();
map.put("tom","美国");
map.put("lily","英国");
map.put("jack","中国");
request.setAttribute("map",map);
// 在JSP中展示数据
<c:forEach items="${requestScope.map}" var="entry">
${entry.key }
${entry.value }<p>
</c:forEach>
3)forEach:指定迭代的次数
<c:forEach begin="start" end="end" step="stepSize">
…循环体代码…
</c:forEach>