EL表达式、JSTL核心标签库

1.1 为什么要使用EL表达式、JSTL核心标签库

  • jsp页面显示动态资源数据,页面会充斥着<%%>等元素,导致页面写代码或观看都非常乱,我们有一个目标将页面上所有的<%%>等全部使用非常简洁的技术代替,让jsp代码写起来简洁和统一,做如下替代:
  • 页面上的脚本代码片段 <% java代码 %>的循环,条件判断等==================使用JSTL技术替代
  • 页面上的脚本表达式<%=java代码%>====================================使用EL技术替代

1.2 EL表达式的基本概述

  • 想要知道什么是EL表达式,它为了解决什么问题而诞生,我们先通过一个场景来了解一下:
    现在有一个需求,在jsp中使用java代码在request中设置四个数据(10 20 30 40)向页面输出(10+20+(30-40))的结果,我们以前的技术是这样实现的: 

<%--
  Created by IntelliJ IDEA.
  User: sunny
  Date: 2019/4/15
  Time: 16:48
  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>
<%--在jsp使用java代码再request中设置四个数据(10 20 30 40 )的
向页面输出(10+20+(30-40))计算结果--%>

<%
    request.setAttribute("num1",10);
    request.setAttribute("num2",20);
    request.setAttribute("num3",30);
    request.setAttribute("num4",40);
%>
java代码输出:<%=(Integer)request.getAttribute("num1")+(Integer)request.getAttribute("num2")+((Integer)request.getAttribute("num3")-(Integer)request.getAttribute("num4"))%>
</body>
</html>
  • 说明:从上面的代码可以发现,使用之前的脚本片段来完成太繁琐了,所以我们需要EL表达式技术来简化java代码的一些操作。EL的全称是Expression Language,作用是代码JSP中的脚本表达式的功能,简化对java代码的操作。

1.3 EL表达式的格式和作用

  1. EL表达式的格式:${表达式内容}

  2. EL表达式的作用:从域对象中查找指定的数据。 

1.4 EL获取容器(域对象)的数据

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--在jsp使用java代码再request中设置四个数据(10 20 30 40 )的
向页面输出(10+20+(30-40))计算结果--%>

<%
    request.setAttribute("num1",10);
    request.setAttribute("num2",20);
    request.setAttribute("num3",30);
    request.setAttribute("num4",40);
%>
使用EL表达式输出:${num1+num2+(num3-num4)}
</body>
</html>

EL表达式、JSTL核心标签库

<%--
  Created by IntelliJ IDEA.
  User: sunny
  Date: 2019/4/15
  Time: 17:14
  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>
<h3>使用el获取三大域对象数据</h3>
<%
    //往各个域里面存储数据
    request.setAttribute("requestName","requestAdmin");
    session.setAttribute("sessionName","sessionAdmin");
    request.getServletContext().setAttribute("servletContextName","servletContextAdmin");
%>
<%--使用el表达式获取域里面的数据--%>
<p>从request里面获取数据:${requestName}</p>
<p>从session里面获取数据:${sessionName}</p>
<p>从ServletContext里面获取数据:${servletContextName}</p>

<%
    //往各个域里面存储数据
    request.setAttribute("name","requestAdmin");
    session.setAttribute("name","sessionAdmin");
    request.getServletContext().setAttribute("name","servletContextAdmin");
%>
<%--输出requestAdmin,el获取域里面的数据会依次从request/session/servletContext获取数据,查找到为止--%>
<p>从域里面获取数据:${name}</p>
<%--要求:获取指定session域里面的name
        el里面可以指定域获取,如下三个对象
            requestScope获取servlet中request域数据
            sessionScope获取servlet中session域数据
            applicationScope获取servlet中servletContext域数据
--%>
<p>从session里面获取name数据:${sessionScope.name}</p>
<p>从servletContext里面获取name数据:${applicationScope.name}</p>
<p>从request里面获取name数据:${requestScope.name}</p>
</body>
</html>

 EL表达式、JSTL核心标签库

  •  我们之前没有指定容器是如何获取数据的呢?其实${addr}在获取容器的时候,默认按request、session、ServletContext顺序获取数据。

1.5 EL获取和解析复杂数据

  • 我们上面的都是简单的字符串,我们接下来获取一些复杂的数据,复杂数据特指:数组、集合(List、Map)和javaBean

1.5.1 获取数组 

<h3>使用el获取域里面各种数据类型的数据——数组类型</h3>
<%
    //往域里面写List
    User[] users = new User[2];
    users[0] = new User("张三",20);
    users[1] = new User("李四",22);
    request.setAttribute("users",users);
%>
<p>获取数组里面第一个元素的userName属性值:${users[0].userName} </p>
<p>获取数组里面第一个元素的age属性值:${users[0].age} </p>
<p>获取数组里面第二个元素的userName属性值:${users[1].userName} </p>
<p>获取数组里面第二个元素的age属性值:${users[1].age} </p>
  • 注意事项:获取数组中某一数据,使用中括号添加角标即可

1.5.2 获取集合 (List Map)

<h3>使用el获取域里面各种数据类型的数据——List类型</h3>
<%
    //往域里面写List
    List<User> userList = new ArrayList<User>();
    userList.add(new User("张三",20));
    userList.add(new User("李四",22));
    request.setAttribute("list",userList);
%>
<p>获取List里面第一个元素的userName属性值:${list[0].userName} </p>
<p>获取List里面第一个元素的age属性值:${list[0].age} </p>
<p>获取List里面第二个元素的userName属性值:${list[1].userName} </p>
<p>获取List里面第二个元素的age属性值:${list[1].age} </p>
<h3>使用el获取域里面各种数据类型的数据——Map类型</h3>
<%
    //往域里面写Map
    Map<String,User> map = new HashMap<String,User>();
    map.put("zhangsan",new User("张三",20));
    map.put("lisi",new User("李四",22));
    request.setAttribute("userMap",map);

%>
<p>获取map里面张三的userName属性值:${userMap.zhangsan.userName} </p>
<p>获取map里面张三的age属性值:${userMap.zhangsan.age} </p>
<p>获取map里面李四的userName属性值:${userMap.lisi.userName} </p>
<p>获取map里面李四的age属性值:${userMap.lisi.age} </p>
  • 注意事项:
  1. 设置map集合数据的key,尽量不要出现“.”
  2. 凡是在EL表达式中使用“.”可以获取的数据,使用“[]”也可以获取

1.5.3 获取javaBean数据

<h3>使用el获取域里面各种数据类型的数据——javaBean类型</h3>
<%
    //往域里面写javaBean
    request.setAttribute("user",new User("张三",20));
    //el获取javaBean数据时直接.属性名就会自动调用属性的get封装方法。
%>
<p>获取user对象里面userName属性值:${user.userName}</p>
<p>获取user对象里面age属性值:${user.age}</p>
  • 注意事项:
  1. JavaBean数据获取类似获取map集合的方式,可以使用“.”获取数据的地方,都可以使用“【】”获取数据
  2. 如果EL表达式获取不到数据,页面没有显示内容,不是显示“null”
  3. EL在获取javaBean的数据时候,底层调用的是getXXX方法

1.6 EL执行运算

  • EL不仅可以用来获取数据,还可以用来执行运算,它包括了算术运算、逻辑运算、比较运算、empty运算符、三元运算
<h3>el的运算符——算数运算符</h3>
<%
    request.setAttribute("x",3);
    request.setAttribute("y",4);
    request.setAttribute("z","5");
%>
${x + y}<br>
${x - y}<br>
${x * y}<br>
${x / y}<br>
${x % y}<br>
<%--注意事项:
    1 在EL中,只要是数字就能执行运算,EL在执行计算的时候,会将数字除尽,最多保留16位小数
    2 在EL中,如果在一个算式中有数据不存在,那么这个数据不参与运算,不报错继续执行。
--%>
${x+y+z}<br>
${x+y+z+a}<br>
<h3>el的empty判空运算符</h3>
<%--
    1.判断是否为null  ,对象为null,返回true
    2.判断是否为空字符串,为空字符串,返回true
    3.判断集合是否有元素,集合元素个数为0,返回true

--%>
<p>空字符串:${empty ""}</p><%--true--%>
<p>空对象:${empty null}</p><%--true--%>
<%
    request.setAttribute("list",new ArrayList<String>());
%>
<p>集合元素个数为0:${empty list}</p><%--true--%>
<%
    List<String> list = new ArrayList<String>();
    list.add("abc");
    request.setAttribute("list",list);
    request.setAttribute("age",18);
%>
<p>集合元素个数为1:${empty list}</p><%--false--%>

<%--
${not empty 域里面的数据}   判空取反
--%>

<%--三目运算符--%>
<p>${ age>16?"成年人":"未成年人"}</p>