• 【JavaWeb】之JSTL & EL表达式



    前言

    本文为JavaWeb基础JSTL & EL表达式相关知识介绍,Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~

    一、JSP标签

    jsp标签的分类:

    • (1)内置标签(动作标签): 不需要在jsp页面导入标签
    • (2)jstl标签: 需要在jsp页面中导入标签
    • (3)自定义标签 : 开发者自行定义,需要在jsp页面导入标签

    内置标签(动作标签)

    • 转发标签:
    <!--语法:-->
    <jsp:forward page="/MyJsp001.jsp"></jsp:forward>
    <!--相当于java代码:--> 
    request.getRequestDispatcher("/MyJsp001.jsp?name=jxf").forward(request, response);
    <!--注意:但是java代码的转发可以通过url带参数的方式进行传递参数,而转发标签需要借助于下面的<jsp:param>标签实现参数传递--> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • jsp:pararm/参数标签:
    <!--语法:-->
    <jsp:param value="jxf" name="name"/> <%-- 传递一个名为name,值为jxf的参数,参数一般作为其他标签的子标签使用--%>
     <!--结合<jsp:forward>标签用法:-->
    <jsp:forward page="/MyJsp001.jsp">
      <jsp:param value="jxf" name="name"/>
    </jsp:forward> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • jsp:include/包含标签:
    <!--语法:-->
    <jsp:include page="/MyJsp001.jsp">
            <jsp:param value="jxf" name="name"/><%--可以将参数传递给包含进来的页面--%>
    </jsp:include>
    
    • 1
    • 2
    • 3
    • 4

    与@inclue包含指令的区别:
    (1)首先是语法不同:;<%@inclue file=“被包含的页面”%>
    (2)jsp:include可以传递参数,<%@inclue%>不可以
    (3)jsp:include:包含页面与被包含页面分别编译为两个java源文件,在运行时引用;<%@inclue%>:包含页面与被包含页面合并编译为一个java源文件

    二、JSTL标签

    1.什么是JSTL

    • JSP标准标识库,使用JSTL可实现JSP页面的逻辑处理; 可用于编写各种动态JSP页面
    • JSTL(Java server pages standarded tag library,即JSP标准标签库)是由JCP(Java community Proces)所制定的标准规范,它主要提供给JavaWeb开发人员一个标准通用的标签库,并由Apache的Jakarta小组来维护。
    • 开发人员可以利用JSTL标签取代JSP页面上的Java代码,从而提高程序的可读性,降低程序的维护难度。

    2.JSTL环境搭建

    导入jar包文件

    • jstl-x.x.jar

    在jsp页面添加taglib指令

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    
    • 1
    • 这里的uri 标识符指向jar包的tld文件,prefix为前缀,可以自定义,一般定义为c;也称为c标签

    使用JSTL标签

    • 刚才用c作为前缀的,那么直接写内容 即可

    3.条件标签 —if

    if标签的几个属性:

    • test:Boolean类型;决定是否处理标签体的内容,即条件判断
    • var:String类型;指定变量名,保存test属性的判断结果
    • scope:String类型;指定var值的作用域范围,默认为page,可选值:page,request,session,application

    代码示例:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%--使用tablib指令指向jstl标签库,定义前缀名prefix--%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    
    <%--
    在test中可写入条件判断(仅有test支持使用el标签),
    var定义属性名,scope声明作用范围(默认为page,即PageContext域对象);
    将该标签的test返回结果自动赋值给var,再由scope决定哪个域对象可以调用;--%>
    <c:if test="${10<20}" var="qwe" scope="application">
        test判断为true:内容可显示!<br/>
    </c:if>
    
    scope指定了作用域,其他域对象获取不到==>
    ${pageScope.qwe}<br/>
    
    上面指定的是application应用程序域对象==>
    ${qwe}
    </body>
    </html>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    启动服务器,页面显示:

    test判断为true:内容可显示!
    scope指定了作用域,其他域对象获取不到==>
    上面指定的是application应用程序域对象==> true
    
    • 1
    • 2
    • 3

    4.迭代标签 —forEach

    forEach对Java中的集合与数组进行遍历

    forEach标签的几个属性:

    • (1)items : 获取需要迭代的集合或数组,支持EL表达式;类型为数组,字符串,集合;
    • (2)var : 定义一个变量,接收循环中获取的数据;不支持EL表达式,类型为String;
    • (3)varStatus : 获取循环的状态信息,不支持 EL表达式,类型为String;varStatus调用的几个参数:常用index,count
    • (4)step : 设置迭代的步长,默认为1; 支持EL表达式,类型为int;
    • (5)end : 设置迭代的结束索引 ,支持EL表达式,类型为int;若指定end属性,则在items的下标到指定end的位置就会结束迭代,若不指定,就全部迭代
    • (6)begin : 设置迭代的开始索引,支持EL表达式,类型为int;若指定begin属性,则从items的下标为begin的位置开始迭代,若不指定,则全部迭代

    代码示例:

    <%
        ArrayList<String> people = new ArrayList<>();
        people.add(0, "张三");
        people.add(1, "李四");
        people.add(2, "王五");
        people.add(3, "赵六");
        people.add(4, "丁一");
        people.add(5, "胡二");
        request.setAttribute("list", people);
    %>
    <%--
    var,每一次遍历出来的变量
    items,要遍历的对象
    begin, 开始位置
    end,   结束位置
    step, 步长
    --%>
    <c:forEach var="people" items="${list}">
        <c:out value="${people}"/>
        <br>
    </c:forEach>
    <hr>
    <c:forEach var="people" items="${list}" begin="1" end="3" step="2">
        <c:out value="${people}"/>
        <br>
    </c:forEach>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    5.迭代标签 —forTokens

    forTokens 用于迭代分隔字符串

    有以下属性:

    • items:需要进行处理的字符串
    • delims :分隔符,可以是数字、字符串或特殊字符
    • var:分隔items的字符串后的定义名
    • varStatus:当前迭代的状态信息
    • step: 迭代的步长
    • begin:设置迭代开始的索引
    • end:设置迭代结束的索引

    代码示例:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%--指定导入的jstl标签库,定义前缀名prefix--%>
    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <%--forTokens 遍历字符串,进行分割--%>
    <%
      String str="学习,forTokens,标,签,Q,WE,R12,3X10:100,500,IO,:,的,";
      request.setAttribute("str",str);
    %>
    <%--使用forTokens分割字符串--%>
    <%-- items:需要遍历的字符串; delims:定义分隔符 ; var: 接收每次分割的字符 --%>
    <c:forTokens items="${str}" delims="," var="ch">
        ${ch}<br/>
    </c:forTokens>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    启动服务器,页面显示:

    学习
    forTokens
    标
    签
    Q
    WE
    R12
    3X10:100
    500
    IO
    :
    的
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    6.格式化日期标签 —formatDate

    格式化日期标签有以下属性:

    • value:Date类型,指定要格式化的目标;
    • pattern:自定义的日期格式,例如:yyyy-MM-dd HH:mm:ss;(不考虑多种语言时可使用pattern)
    • var:存储格式化日期的变量名
    • type:值:time或date或both。控制仅出现时间,仅出现日期,或者都出现
    • dateStyle:指定日期显示格式,值:SHORT,MEDIUM,LONG,FULL(默认)
    • timeStyle:指定时间显示格式 ,值:SHORT,MEDIUM,LONG,FULL(默认)
    • scope:存储格式化日志变量的范围

    代码示例:

    <%@ page import="java.util.Date" %>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%--指定导入的jstl标签库;定义前缀名prefix--%>
    <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    
    <%--将当前时间赋值给请求对象的自定义属性now;--%>
    <%
      request.setAttribute("now",new Date());
    %>
    <%--value: 指定要格式化的目标, pattern:设置格式化的格式(规则)--%>
    <fmt:formatDate value="${now}" pattern="yyyy年MM月dd日 HH时mm分ss秒"/>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    启动服务器,页面显示:

    2022年10月19日 19时30分45秒
    
    • 1

    三、EL表达式

    1.EL表达式简介

    • EL表达式全称:Expression Language,即表达式语言
    • EL表达式作用:代替JSP页面中表达式脚本进行数据的输出
    • EL表达式比JSP的表达式脚本简洁很多
    • EL表达式的格式是:${表达式} ,注:EL表达式写在jsp页面中,表达式一般是域对象的key

    代码示例:

    <body>
        <%
            request.setAttribute("key", "value");		
        %>
        <%--  表达式脚本输出key1的值  --%>
        <%=request.getAttribute("key1")%>
        <%--  EL表达式输出key1的值  --%>
        ${key1}
        <%--  表达式脚本输出null值时页面显示null
              EL表达式输出null值时页面什么都不显示(空串)--%>
    </body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    启动服务器,页面显示:

    null
    
    • 1

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

    • EL表达式主要是输出域对象中的数据,当四个域对象都有同一个key的值时,EL表达式会按照四个域对象的范围从小到大进行搜索,找到就输出,与四个域对象声明的先后顺序无关

    代码示例:

    <body>
        <%							  
            //向四个域对象中都保存相同key的值
            request.setAttribute("key", "request");
            session.setAttribute("key", "session");
            application.setAttribute("key", "application");
            pageContext.setAttribute("key", "pageContext");
        %>
        <%--  使用EL表达式输出key的值  --%>
        ${key}
    </body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    启动服务器,页面显示:

    pageContext
    
    • 1

    3.EL表达式输出Java类的属性

    代码示例:
    创建Person类

    public class Person {
        private String name;
        private String city;
        public int age;
        //以及全参、空参构造器,各属性的getter/setter方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在web目录下创建Test.jsp

    <body>
        <%
            Person person = new Person();
            person.setName("JayChou");
            person.setCity("上海");
            person.setAge(35);
           
            pageContext.setAttribute("p", person);
        %>
        <%--EL表达式中对象名.属性名不找属性的值,而是找名字对应的getXxx方法,没有此方法会报错--%>
        输出Person:${ p }<br/>
        输出Person的name属性:${p.name} <br>
        输出Person的city属性:${p.city} <br>
        输出Person的age属性:${p.city} <br>
    </body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    启动服务器,页面显示:

    输出Person:Person{name=JayChou,city=上海,age=35}
    输出Person的name属性JayChou
    输出Person的city属性:上海
    输出Person的age属性:35
    
    • 1
    • 2
    • 3
    • 4

    4.EL表达式的运算

    语法:${运算表达式}

    EL表达式支持以下运算符:

    • 关系运算
    • 逻辑运算
    • 算数运算
    • empty运算:empty运算可以判断一个数据是否为空,若为空,输出true,不为空,输出false
    • 三元运算:表达式 1?表达式 2:表达式 3;表达式1为真返回表达式2的值,表达式1为假返回表达式3的值
    • “.”点运算和“[ ]”中括号运算:点运算可以输出某个对象的某个属性的值(getXxx或isXxx方法返回的值)
      中括号运算可以输出有序集合中某个元素的值

    5.EL表达式的11个隐含对象

    在这里插入图片描述
    (1) pageScope、requestScope、sessionScope、applicationScope对象的使用

    <body>
        <%
            pageContext.setAttribute("key1", "pageContext1");
            pageContext.setAttribute("key2", "pageContext2");
            request.setAttribute("key2", "request");
            session.setAttribute("key2", "session");
            application.setAttribute("key2", "application");
        %>
        <%--  获取特定域中的属性  --%>
        ${ pageScope.key1 } <br>
        ${ applicationScope.key2 }
        <%--  若直接获取key1或key2依然按照之前范围从小到大检索,无法获取指定域  --%>
    </body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    运行结果:
    在这里插入图片描述

    (2) pageContext对象的使用

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <%-- 先通过pageContext对象获取request、session对象,再获取以下内容 --%>
        <%--
            获取请求的协议:request.getScheme()
            获取请求的服务器ip或域名:request.getServerName()
            获取请求的服务器端口号:request.getServerPort()
            获取当前工程路径:request.getContextPath()
            获取请求的方式:request.getMethod()
            获取客户端的ip地址:request.getRemoteHost()
            获取会话的唯一标识: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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    运行结果:
    在这里插入图片描述
    (3) param、paramValues对象的使用

    <body>
        获取请求参数username的值:${ param.username } <br>
        获取请求参数password的值:${ param.password } <br>
        获取请求参数中第一个hobby的值:${ paramValues.hobby[0] } <br>
        获取请求参数中第二个hobby的值:${ paramValues.hobby[1] } <br>
        <%--  有多个同名的key时使用paramValues的索引值决定获取哪一个,使用param只可获取第一个  --%>
        使用param获取hobby的值:${ param.hobby } <br>
    </body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    运行结果:
    浏览器地址栏输入:http://localhost:8080/MyTest/Test.jsp?username=Jaychou&password=123&hobby=sing&hobby=dance
    在这里插入图片描述

    (4) header、headerValues对象的使用

    <body>
        输出请求头[user-Agent]的值:${ header["User-Agent"] }<br>
        输出请求头中第一个[user-Agent]的值:${ headerValues["User-Agent"][0] }<br>
    </body>
    
    • 1
    • 2
    • 3
    • 4

    (5) cookie对象的使用

    <body>
        获取Cookie的名称:${ cookie.JSESSIONID.name } <br>
        获取Cookie的值:${ cookie.JSESSIONID.value } <br>
    </body>
    
    • 1
    • 2
    • 3
    • 4

    运行结果:
    在这里插入图片描述

    (6) initParam对象的使用

    在web.xml中写参数 (修改了web.xml中内容之后,需要重启服务才可生效):

    <context-param>
        <param-name>usernameparam-name>
        <param-value>rootparam-value>
    context-param>
    <context-param>
        <param-name>urlparam-name>
        <param-value>jdbc:mysql:///testparam-value>
    context-param>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    test.jsp:

    <body>
        输出&lt;Context-param&gt;username的值:${ initParam.username } <br>
        输出&lt;Context-param&gt;url的值:${ initParam.url } <br>
    </body>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    运行结果:
    在这里插入图片描述

    后记

    Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~

  • 相关阅读:
    python实现图片与视频转换:将视频保存为图片,将批量图片保存为视频
    【Redis学习笔记】第二章【2.4】Redis数据类型--set
    Android程序设计之音乐播放器实现
    最大单词长度乘积(w位运算)
    转换张量形状:`nlc_to_nchw` 函数详解
    Linux常用快捷键汇总
    LeetCode——半有序排列
    个人能做股票期权吗?个人期权交易开户条件新规
    代码随想录算法训练营002| 59. 螺旋矩阵 II,209. 长度最小的子数组,977. 有序数组的平方
    Web3和区块链入门——Web3历史和Web3是什么?
  • 原文地址:https://blog.csdn.net/qq_42146402/article/details/127416734