EL表达式和JSTL标签库
什么是EL表达式以及他的作用
- EL表达式和jsp表达式脚本输出对比
- a.jsp
<%--
Created by IntelliJ IDEA.
User: SWT
Date: 2023/9/14
Time: 22:59
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
//先保存一个数据
request.setAttribute("key","value");
%>
jsp表达式脚本输出的值是: <%=request.getAttribute("key")%> <br>
EL表达式输出的值是:${key};
</body>
</html>
1.从上面可以看出EL的写法更加简洁
- 2.当我们的数据为空时,EL的输出对用户更加友好
EL表达式搜索四个域的顺序
-
需要先理解四个域所表示的范围
-
a.jsp
<%--
Created by IntelliJ IDEA.
User: SWT
Date: 2023/9/14
Time: 22:59
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
//往域中保存数据
request.setAttribute("key","request");
session.setAttribute("key","session");
pageContext.setAttribute("key","pageContext");
application.setAttribute("key","application");
%>
${key}
</body>
</html>
现在我们访问a.jsp这个地址,出来的是pageContext域中的数据,因为他的范围最小
-
1.当我们注释掉** pageContext.setAttribute("key","pageContext");**后,重新访问0
**出现的应该是request域中的数据(他的范围最小) -
- 我们 request.setAttribute("key","request");也注释掉,从新范围
**出现的应该是session域中的数据,因为重新访问已经是新的请求了,request的数据不在了
- 我们 request.setAttribute("key","request");也注释掉,从新范围
-
3.我们再将 session.setAttribute("key","session");注释掉从新访问
**出现的还是session的数据,因为浏览器,没关闭还是一次会话
我们关闭浏览器,从新打开访问时,出现的就是application了 -
服务器关闭后application 就没有了
EL表达式输出复杂的Bean对象
-
E表达式主要用于输出域中的数据,前面的我们域中只是简单的字符串,但是如果我们域中数据是一个复杂的javaBean对象,这该怎么输出呢
-
直接输出数组名,输出的是数组地址
-
Person类
package com.test;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/* i.需求——输出 Person 类中普通属性,数组属性。list 集合属性和 map 集合属性。*/
public class Person {
private String name;
private String[] phones;
private List<String> cities;
private Map<String,Object> map;
public Person() {
}
public Person(String name, String[] phones, List<String> cities, Map<String, Object> map) {
this.name = name;
this.phones = phones;
this.cities = cities;
this.map = map;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return phones
*/
public String[] getPhones() {
return phones;
}
/**
* 设置
* @param phones
*/
public void setPhones(String[] phones) {
this.phones = phones;
}
/**
* 获取
* @return cities
*/
public List<String> getCities() {
return cities;
}
/**
* 设置
* @param cities
*/
public void setCities(List<String> cities) {
this.cities = cities;
}
/**
* 获取
* @return map
*/
public Map<String, Object> getMap() {
return map;
}
/**
* 设置
* @param map
*/
public void setMap(Map<String, Object> map) {
this.map = map;
}
public String toString() {
return "Person{name = " + name + ", phones = "+ Arrays.toString(phones)+ ", cities = " + cities + ", map = " + map + "}";
}
}
person.jsp
package com.test;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/* i.需求——输出 Person 类中普通属性,数组属性。list 集合属性和 map 集合属性。*/
public class Person {
private String name;
private String[] phones;
private List<String> cities;
private Map<String,Object> map;
public Person() {
}
public Person(String name, String[] phones, List<String> cities, Map<String, Object> map) {
this.name = name;
this.phones = phones;
this.cities = cities;
this.map = map;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return phones
*/
public String[] getPhones() {
return phones;
}
/**
* 设置
* @param phones
*/
public void setPhones(String[] phones) {
this.phones = phones;
}
/**
* 获取
* @return cities
*/
public List<String> getCities() {
return cities;
}
/**
* 设置
* @param cities
*/
public void setCities(List<String> cities) {
this.cities = cities;
}
/**
* 获取
* @return map
*/
public Map<String, Object> getMap() {
return map;
}
/**
* 设置
* @param map
*/
public void setMap(Map<String, Object> map) {
this.map = map;
}
public String toString() {
return "Person{name = " + name + ", phones = "+ Arrays.toString(phones)+ ", cities = " + cities + ", map = " + map + "}";
}
}
- 从前面可以看出都是person.属性名进行访问,真的都是这样吗
- 访问出错
- 此时可以访问成功
- 此时也可以访问成功
得出一个结论:我们的LE表达式访问属性:是直接调用该输出对应的Getter方法
LS表达式出来输出域对象,还能做一些简单的运算,然后将运算的结果输出
关系运算
- 示例
逻辑运算
- 示例
算数运算符
- 在a/b时EL为了兼容为小数的情况,将a/b为整数也转化为小数显示了
- 示例
empty运算
<%@ page import="com.test.Person" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Map" %><%--
Created by IntelliJ IDEA.
User: SWT
Date: 2023/9/20
Time: 19:01
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<%
//1、值为 null 值的时候,为空
request.setAttribute("emptyNull",null);
//2、值为空串的时候,为空
String str = "";
request.setAttribute("strNull",str);
//3、值是 Object 类型数组,长度为零的时候
Integer []arr = {};
request.setAttribute("arrNull",arr);
//4、list 集合,元素个数为零
List<String> list = new ArrayList<>();
request.setAttribute("listNull",list);
//5、map 集合,元素个数位零
Map<String,Object> map= new HashMap<>();
request.setAttribute("mapNull",map);
%>
${empty emptyNull}<br>
${empty strNull}<br>
${empty arrNull}<br>
${empty listNull}<br>
${empty mapNull}<br>
</head>
<body>
</body>
</html>
- 三元运算符
- 举例
点运算和中括号运算
-
特殊字符:指的的是在我们运算过程中用到的一些运算符,如:+-.等
-
演示:[]输出map集合的情况
EL表达式11个隐含对象介绍
隐含对象之四个域对象的使用
pageContext隐含对象
- 输出
<%--
Created by IntelliJ IDEA.
User: SWT
Date: 2023/9/20
Time: 20:25
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
request.getScheme() 它可以获取请求的协议
request.getServerName() 获取请求的服务器 ip 或域名
request.getServerPort() 获取请求的服务器端口号
getContextPath() 获取当前工程路径
request.getMethod() 获取请求的方式(GET 或 POST)
request.getRemoteHost() 获取客户端的 ip 地址
session.getId() 获取会话的唯一标识
--%>
1. 协议:${pageContext.request.scheme}<br>
2. 服务器 ip:${pageContext.request.serverName}<br>
3. 服务器端口:${pageContext.request.serverPort}<br>
4. 获取工程路径:${pageContext.request.contextPath}<br>
5. 获取请求方法(方式):${pageContext.request.method}<br>
6. 获取客户端 ip 地址:${pageContext.request.remoteHost}<br>
7. 获取会话的 id 编号:${pageContext.session.id}<br>
</body>
</html>
- 输出
- 好像感觉这样输出比使用脚本输出更复杂,一般企业的解决方案:
其他EL隐含对象的示例
- 1.获取请求参数
- jsp文件
<%--
Created by IntelliJ IDEA.
User: SWT
Date: 2023/9/21
Time: 10:35
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>演示其他的EL隐含对象</title>
</head>
<body>
获取请求参数的对象:<br>
获取请求参数username的值:${param.username}<br>
获取请求参数password的值:${param.password}<br>
获取请求参数hobby的值:${paramValues.hobby[0]}<br>
获取请求参数hobby的值:${paramValues.hobby[1]}<br>
</body>
</html>
经验总结:我们可以通过EL表达式输出的信息大多都是以key=value键值对的形式常出现的
- 2.获取请求头信息
-
当我们的请求头有多个值的时候用headerValues输出
-
cookie和initParam对象
注意:当我们修改的是配置文件,如:web.xml一定要重新部署才能够生效 -
在web.xml中配置context-param的信息
JSTL标签库
JSTL标签库介绍
标签库的使用步骤
core核心库使用
set标签
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: SWT
Date: 2023/9/21
Time: 19:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%-- i.<c:set />
作用:set 标签可以往域中保存数据
域对象.setAttribute(key,value);
scope 属性设置保存到哪个域
page 表示 PageContext 域(默认值)
request 表示 Request 域
session 表示 Session 域
application 表示 ServletContext 域
var 属性设置 key 是多少
value 属性设置值
--%>
<%--JSTL标签用来替代代码脚本--%>
保存前之前:${requestScope.abc}<br>
<c:set scope="request" var="abc" value="abcValue"></c:set>
保存之后:${requestScope.abc}<br>
</body>
</html>
if标签
. <c:choose> <c:when> <c:otherwise>标(和swich--case..default很像)
- 使用这三标签替代IF-ELSE做多路判断
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: SWT
Date: 2023/9/21
Time: 20:21
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
iii.<c:choose> <c:when> <c:otherwise>标签
作用:多路判断。跟 switch ... case .... default 非常接近
choose 标签开始选择判断
when 标签表示每一种判断情况
test 属性表示当前这种判断情况的值
otherwise 标签表示剩下的情况
<c:choose> <c:when> <c:otherwise>标签使用时需要注意的点:
1、标签里不能使用 html 注释,要使用 jsp 注释
2、when 标签的父标签一定要是 choose 标签
--%>
<%
request.setAttribute("height",178);//先往域中保存数据
%>
<c:choose >
<c:when test="${requestScope.height>190}">
<h1>小巨人</h1>
</c:when>
<c:when test="${requestScope.height>180}">
<h1>还可以</h1>
</c:when>
<c:otherwise>
<h1>三级残废</h1>
</c:otherwise>
</c:choose>
</body>
</html>
注意:这种形式的选择结构,从上往下执行。当有符合条件的将会执行,并且执行完后自动跳出整个choose,不需要break(这是和java中swich..case结构的本质区别)
- 注意:
1、标签里不能使用 html 注释,要使用 jsp 注释
2、when 标签的父标签一定要是 choose 标签 - 当when父标签不是choose将会抛出异常
. <c:forEach />标签
情景1. 遍历 1 到 10,输出
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: SWT
Date: 2023/9/21
Time: 20:52
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--遍历输出1到10--%>
<%--1.遍历 1 到 10,输出
begin 属性设置开始的索引
end 属性设置结束的索引
var 属性表示循环的变量(也是当前正在遍历到的数据)
相当于:for (int i = 0; i <= 10; i++)
--%>
<table>
<tr>
<c:forEach begin="0" end="10" var="i">
<td>
第 ${i}行
</td>
</c:forEach>
</tr>
</table>
</body>
</html>
- 可以用table修饰一下输出的
使用forEach遍历object数组
forEach遍历输出Map集合
使用forEach遍历List集合
- Student类
package com.pojo;
public class Student {
private Integer id;
private String name;
private Integer age;
private String phone;
public Student() {
}
public Student(Integer id, String name, Integer age, String phone) {
this.id = id;
this.name = name;
this.age = age;
this.phone = phone;
}
/**
* 获取
* @return id
*/
public Integer getId() {
return id;
}
/**
* 设置
* @param id
*/
public void setId(Integer id) {
this.id = id;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public Integer getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(Integer age) {
this.age = age;
}
/**
* 获取
* @return phone
*/
public String getPhone() {
return phone;
}
/**
* 设置
* @param phone
*/
public void setPhone(String phone) {
this.phone = phone;
}
public String toString() {
return "Student{id = " + id + ", name = " + name + ", age = " + age + ", phone = " + phone + "}";
}
}
- jsp文件
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.util.List" %>
<%@ page import="com.pojo.Student" %>
<%@ page import="java.util.ArrayList" %><%--
Created by IntelliJ IDEA.
User: SWT
Date: 2023/9/22
Time: 8:23
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>遍历List集合</title>
</head>
<body>
<%
List<Student> studentList = new ArrayList<>();
//给集合赋值
for (int i = 1; i < 10; i++) {
studentList.add(new Student(i,"name"+i,18+i,"phone"+i));
}
//将集合添加到域中
request.setAttribute("studentList",studentList);
%>
<table>
<tr>
<td>id</td>
<td>姓名</td>
<td>年龄</td>
<td>电话</td>
<td>操作</td>
</tr>
<c:forEach items="${requestScope.studentList}" var="student">
<tr>
<td>${student.id}</td>
<td> ${student.name}</td>
<td>${student.age}</td>
<td>${student.phone}</td>
<td>${"插入 删除"}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
- 可以给标签加上样式,这样更好看
forEach标签所有属性组合使用介绍
-
输出的时候带有$表示内部类
-
注意点:
-
详解:
varStatus="status"
注意点:当我们的属性是boolean类型的,生成的get方法是isxxx。和getter方法作用相同。在EL表达式中也会调用isxxx方法
有了Status类中实现的一些,方法,对我们的遍历输出更加方便