EL表达式和JSTL标签库

发布时间 2023-09-22 09:44:44作者: 一往而深,

什么是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域中的数据(他的范围最小)

    1. 我们 request.setAttribute("key","request");也注释掉,从新范围
      **出现的应该是session域中的数据,因为重新访问已经是新的请求了,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类中实现的一些,方法,对我们的遍历输出更加方便