【JavaWeb - 网页编程】九 EL 表达式与 JSTL 标签库

发布于:2023-01-18 ⋅ 阅读:(476) ⋅ 点赞:(0)


第九章 EL 表达式与 JSTL 标签库

创作日期:2021-12-28


9.1 EL 表达式简介

9.1.1 什么是 EL 表达式

EL 表达式的全称为:Expression Language 是表达式语言


9.1.2 EL 表达式的作用

        EL 表达式主要代替 jsp 页面中的表达式脚本在 jsp 页面中进行数据的输出,因为 EL 表达式在输出数据的时候,要比 JSP 的表达式脚本更加简介

<%-- PrintHtml.jsp --%>
<body>
<%
    request.setAttribute("key", "123");
%>
JSP 表达式脚本输出 key 的值为:<%= request.getAttribute("key")%><br>
EL 表达式输出 key 的值为:${key}
</body>


9.1.3 EL 表达式搜索域数据的顺序

        EL 表达式主要是在 JSP 页面中输出数据,主要是输出域对象中的数据,当四个域对象中都有相同的 key 的数据的时候,EL 表达式会按照这四个域的范围由小到大的顺序进行搜索并输出,顺序为:pageContext 域,request 域,session 域 ,application 域

<%-- PrintHtml.jsp --%>
<body>
输出优先级为:pageContext 域,request 域,session 域 ,application 域
<%
    pageContext.setAttribute("key", "123");
    request.setAttribute("key", "123");
    session.setAttribute("key", "123");
    application.setAttribute("key", "123");
%>
</body>

9.1.4 EL表达式输出属性数据

EL 表达式支持输出 Bean 的普通属性,数组属性,List 集合属性,map 集合属性

演示:

创建测试类:

package com.jsp.text;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @Description:测试类
 * @author: XFDQ.lmq
 * @create: 2022-08-11 18:01
 */
public class Person {
    private String name;
    private Integer[] Phones;
    private List<String> citys;
    private Map<String,Integer> results;

    public Person() {
    }

    public Person(String name, Integer[] phones, List<String> citys, Map<String, Integer> results) {
        this.name = name;
        Phones = phones;
        this.citys = citys;
        this.results = results;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer[] getPhones() {
        return Phones;
    }

    public void setPhones(Integer[] phones) {
        Phones = phones;
    }

    public List<String> getCitys() {
        return citys;
    }

    public void setCitys(List<String> citys) {
        this.citys = citys;
    }

    public Map<String, Integer> getResults() {
        return results;
    }

    public void setResults(Map<String, Integer> results) {
        this.results = results;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", Phones=" + Arrays.toString(Phones) +
                ", citys=" + citys +
                ", results=" + results +
                '}';
    }
}
<%-- EL.jsp --%>
<body>
<%
    LinkedList<String> cityLinkedList = new LinkedList<>();
    cityLinkedList.add("China");
    cityLinkedList.add("America");
    cityLinkedList.add("Canada");

    HashMap<String,Integer> resultsHashMap = new HashMap<>();
    resultsHashMap.put("数学",92);
    resultsHashMap.put("语文",98);
    resultsHashMap.put("英语",90);

    Person person = new Person();
    person.setName("xfdq");
    person.setPhones(new Integer[]{151,159});
    person.setCitys(cityLinkedList);
    person.setResults(resultsHashMap);
    pageContext.setAttribute("person",person);
%>
    输出Person:${person}<br>
    输出Person的name属性:${person.name}<br>
    输出Person的phones属性:${person.phones[0]}<br>
    输出Person的citys属性:${person.citys[1]}<br>
    输出Person的results属性:${person.results.get("数学")}分<br>
</body>


9.2 EL 表达式的运算

语法:${ 运算表达式 },EL 表达式支持如下运算符:

9.2.1 关系运算

<body>
比较结果:${2 == 4},a 不等于 b<br>
比较结果:${2 != 4},a 不等于 b<br>
比较结果:${2 > 4},a 小于 b<br>
比较结果:${2 < 4},a 小于 b<br>
比较结果:${2 >= 4},a 小于等于 b<br>
比较结果:${2 <= 4},a 小于等于 b
</body>


9.2.2 逻辑运算

<body>
比较结果:${2 == 4 && 2 < 4},false<br>
比较结果:${2 != 4 || 2 > 4},true<br>
比较结果:${!(2 < 4)},false<br>
</body>


9.2.3 算数运算

<body>
2 + 2 = ${2+2}<br>
2 - 2 = ${2-2}<br>
2 * 2 = ${2*2}<br>
2 / 2 = ${2/2}<br>
2 % 2 = ${2%2}<br>
</body>


9.2.4 empty 运算与三元运算

  • empty 运算可以判断一个数据是否为空,如果为空,则输出 true,不为空输出 false
    • 值为 null 值的时候,为空
    • 值为 空串 的时候,为空
    • 值是 Object 类型数组,长度为零的时候
    • list 集合,元素个数为零
    • map 集合,元素个数为零
<body>
<%
    //1.值为 null 值的时候,为空
    request.setAttribute("emptyNull", null);
    //2.值为 空串 的时候,为空
    request.setAttribute("emptyStr", "");
    //3.值是 Object 类型数组,长度为零的时候
    request.setAttribute("emptyArr",new Object[]{});
    //4.list 集合,元素个数为零
    List<String> stringList = new LinkedList<>();
    request.setAttribute("emptyList", stringList);
    //5.map 集合,元素个数为零
    Map<String,Integer> stringIntegerMap = new HashMap<>();
    request.setAttribute("emptyMap",stringIntegerMap );
%>
${empty emptyNull},为空<br>
${empty emptyStr},为空<br>
${empty emptyArr},为空<br>
${empty emptyList},为空<br>
${empty emptyMap},为空<br>
</body>

  • 三元运算语法:表达式1?表达式2:表达式3,如果表达式1的值为真,返回表达式2的值,如果为假返回表达式3的值

<body>
${1>2?1+2:2-1},1<br>
</body>


9.2.5 点运算和中括号运算符

  • 点运算可以输出 Bean 对象中某个属性的值
  • 中括号运算可以输出有序集合中某个元素的值,并且还可以输出 map 集合里包含有特殊字符的 key 值
<body>
<%
    Map map = new HashMap();
    map.put("bbb","bbbvalue");
    map.put("a+a+a","aaavlue");
    request.setAttribute("map",map);
%>
${map.bbb}
${map["a+a+a"]}
</body>


9.3 EL 表达式的 11 个隐含对象

EL 表达式中 11 个隐含对象是 EL 表达式中自己定义的,可以直接使用

9.3.1 EL 表达式获取四个特定域中的属性

  • 变量:pageScope
    • 类型:Map<String,Object>,作用:获取 pageContext 域中的数据
  • 变量:requestScope
    • 类型:Map<String,Object>,作用:获取 Request 域中的数据
  • 变量:sessionScope
    • 类型:Map<String,Object>,作用:获取 Session 域中的数据
  • 变量:applicationScope
    • 类型:Map<String,Object>,作用:获取 ServletContext 域中的数据
<body>
<%
    pageContext.setAttribute("key1", "value1");
    request.setAttribute("key2", "value2");
    session.setAttribute("key3", "value3");
    application.setAttribute("key4", "value4");
%>
pageContext 域中的数据:${pageScope.key1}<br>
Request 域中的数据:${requestScope.key2}<br>
Session 域中的数据:${sessionScope.key3}<br>
ServletContext 域中的数据:${applicationScope.key4}<br>
</body>


9.3.2 pageContext 对象的使用

  • 变量:pageContext
    • 类型:PageContextImpl,作用:获取 JSP 中的九大内置对象
<body>
<%--
    request.getScheme():获取请求的协议
    request.getServerName():获取请求的服务器 IP 或者域名
    request.getServerPort():获取请求的服务器端口号
    request.getContextPath():获取当前工程路径
    request.getMethod():获取请求的方式(POST/GET)
    request.getRemoteHost():获取客户端的 ip 地址
    request.getId():获取会话的唯一标识
--%>
<%
pageContext.setAttribute("req",request);
%>
1.协议:${req.scheme} <br>
2.服务器 IP:${req.serverName} <br>
3.服务器端口: ${req.serverPort}<br>
4.获取工程路径: ${req.servletPath}<br>
5.获取请求方法: ${req.method} <br>
6.获取客户端 IP 地址: ${req.remoteHost} <br>
7.获取会话的 ID 编号: ${req.session.id}<br>
</body>


9.3.3 EL 表达式其他隐含对象的使用

  • 变量:param
    • 类型:Map<String,String>,作用:获取请求参数的值
  • 变量:paramValues
    • 类型:Map<String,String[]>,作用:获取多个请求参数的值
  • 变量:header
    • 类型:Map<String,String>,作用:获取请求头的信息
  • 变量:headerValues
    • 类型:Map<String,String[]>,作用:获取多个请求头的信息
  • 变量:cookie
    • 类型:Map<String,Cookie>,作用:获取当前请求的 Cookie 的值
  • 变量:initParam
    • 类型:Map<String,String>,作用:获取在 web.xml 中配置的 <context-param> 上下文参数
<body>
获取 Cookie 的名称:${cookie.JSESSIONID.name}<br>
获取 Cookie 的值:${cookie.JSESSIONID.value}
</body>


9.4 JSTL 标签库

9.4.1 JSTL 标签库的简介

    JSTL 标签库,全称是指 JSP Standard Tag Libray JSP 标准标签库,是一个不断完善的开放源代码的 JSP 标签库,EL 表达式主要是为了替换 JSP 中的表达式脚本,而标签库是为了替换代码脚本,这样使得整个 JSP 页面变得更加简介

JSTL 由五个不同功能的标签库组成:


9.4.2 JSTL 标签库的使用步骤

  • 导入 JSTL 标签库的 jar 包

  • 使用 taglib 指令引入标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

9.4.3 core 核心库的使用

  • <c:set></c:set> 标签:可以往域中保存数据
    • scope 属性:设置保存到哪个域中
    • var 属性:设置域中 key 
    • value 属性:设置域中 key 的值
  • <c:if></c:if> 标签:做 if 判断
    • test 属性:设置判断条件(使用 EL 表达式)
  • <c:choose><c:when><c:otherwise> 标签:多个判断条件
    • test 属性:设置判断条件(使用 EL 表达式)
  • <c:forEach> 标签:遍历输出
    • begin 属性:设置开始的索引
    • end 属性:设置结束的索引
    • var 属性:设置循环的变量
<body>
<c:set scope="page" var="xfdq" value="jsb"></c:set>
xfdq:${pageScope.xfdq}<br>

<c:if test="${pageScope.xfdq != null}">
    xfdq:${pageScope.xfdq}<br>
</c:if>

<%
    request.setAttribute("jsb", 19);
%>
<c:choose>
    <c:when test="${requestScope.jsb >20}">
        <div>人多</div>
    </c:when>
    <c:otherwise>
        <div>人少</div>
    </c:otherwise>
</c:choose>

<%-- forEach:遍历 1 到 10 --%>
<c:forEach begin="1" end="10" var="i">
    ${i}
</c:forEach><br>

<%-- 遍历 Object 数组 --%>
<%
    request.setAttribute("arr",new Integer[]{123,234,345,456,567,678,789,890});
%>
<c:forEach items="${requestScope.arr}" var="item">
    ${item}
</c:forEach><br>

<%-- 遍历 Map 集合 --%>
<%
    HashMap map = new HashMap();
    map.put("key1","aaa");
    map.put("key2","bbb");
    map.put("key3","ccc");
    map.put("key4","ddd");
    request.setAttribute("map",map);
%>
<c:forEach items="${requestScope.map}" var="entry">
    ${entry.key} = ${entry.value}
</c:forEach><br>
</body>


9.5 文件的上传和下载

9.5.1 文件的上传操作

  • 创建 form 标签,设置 method 属性为 post 请求
  • form 标签的 encType 属性值必须为 multipart/form-data 值
  • 在 form 标签中使用 input type=file 添加上传的文件
  • 导入 jar 包:commons-fileupload-1.3.jar
  • 编写服务器代码接收,处理上传的数据
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <welcome-file-list>
        <welcome-file>EL.jsp</welcome-file>
    </welcome-file-list>
    <servlet>
        <servlet-name>UpFile</servlet-name>
        <servlet-class>com.jsp.servlet.UpFile</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>UpFile</servlet-name>
        <url-pattern>/upfile</url-pattern>
    </servlet-mapping>
    <listener>
        <listener-class>com.jsp.Listener.ServletContextListenerImpl</listener-class>
    </listener>
</web-app>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="http://localhost:8080/Jsp_web/upfile" method="post" enctype="multipart/form-data">
    用户名:<input type="text" name="userName"><br>
    头像:<input type="file" name="photo"><br>
    <input type="submit" value="上传">
</form>
</body>
</html>
package com.jsp.servlet;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * @Description:文件上传与下载
 * @author: XFDQ.lmq
 * @create: 2022-08-06 17:38
 */
public class UpFile extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.先判断上传的数据是否为多段数据(只有是多段的数据,才是文件上传的)
        if (ServletFileUpload.isMultipartContent(req)) {
            //2.创建 FileItemFactory 工厂实现类
            FileItemFactory fileItemFactory = new DiskFileItemFactory();
            //3.创建用于解析上传数据的工具类 ServletFileUpload 类
            ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
            try {
                //4.解析上传的数据,得到每一个表单项 FileItem
                List<FileItem> fileItems = servletFileUpload.parseRequest(req);
                System.out.println(fileItems);
                //5.循环判断,每一个表单项是普通类型还是上传类型
                for (FileItem f : fileItems) {
                    if (f.isFormField()) {
                        //普通表单项
                        System.out.println("表单项的 name 属性值:" + f.getFieldName());
                        //参数 "utf-8" 解决乱码问题
                        System.out.println("表单项的 name 属性值:" + f.getString("UTF-8"));
                    } else {
                        //上传的文件
                        System.out.println("表单项的 name 属性值:" + f.getFieldName());
                        System.out.println("上传的文件名:" + f.getName());
                        f.write(new File("G:\\照片"+f.getName()));
                    }
                }
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }
}


9.5.2 文件的下载操作

  • 获取需要下载的文件名
  • 读取要下载的文件内容
  • 把下载的文件内容回传给客户端
  • 在回传前,通过响应头告诉客户端返回的数据类型
  • 通过响应头告诉客户端收到的数据是用于下载使用
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <welcome-file-list>
        <welcome-file>EL.jsp</welcome-file>
    </welcome-file-list>
    <servlet>
        <servlet-name>UpFile</servlet-name>
        <servlet-class>com.jsp.servlet.UpFile</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>UpFile</servlet-name>
        <url-pattern>/upfile</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>Download</servlet-name>
        <servlet-class>com.jsp.servlet.Download</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Download</servlet-name>
        <url-pattern>/download</url-pattern>
    </servlet-mapping>

    <listener>
        <listener-class>com.jsp.Listener.ServletContextListenerImpl</listener-class>
    </listener>
</web-app>

package com.jsp.servlet;

import org.apache.commons.io.IOUtils;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

/**
 * @Description:文件下载
 * @author: XFDQ.lmq
 * @create: 2022-08-16 14:45
 */
public class Download extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取需要下载的文件名
        String downloadFileName = "66.jpg";
        //2.读取要下载的文件内容
        ServletContext servletContext = getServletContext();
        //3.获取要下载文件的类型
        String mimeType = servletContext.getMimeType("/file/" + downloadFileName);
        //4.在回传前,通过响应头告诉客户端返回的数据类型
        resp.setContentType(mimeType);
        //5.通过响应头告诉客户端收到的数据是用于下载使用
        /*
         * Content-Disposition 表示怎么处理收到的数据
         * attachment 表示下载使用
         * filename 表示下载的文件名
         * */
        resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("Java.jpg", "UTF-8"));
        //6.获取输入流
        InputStream resourceAsStream = servletContext.getResourceAsStream("/file/" + downloadFileName);
        //7.获取响应的输出流
        OutputStream outputStream = resp.getOutputStream();
        //8.读取输入流中的全部数据,复制给输出流,输出给客户端
        IOUtils.copy(resourceAsStream, outputStream);

    }
}

上一节:

下一节:

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到