JSP、EL表达式、JSTL标签库干货(建议收藏)

隐式获取

${key} : 将会以pageContext👉request👉session👉application顺序读取,域的范围是从小到大

关于集合的展示 🔻

<%

List list = new ArrayList();

    list.add("one");

    list.add("two");

    list.add("three");

    pageContext.setAttribute("aList",list);

    Map map = new HashMap();

    map.put("color","red");

    map.put("shape","square");

    pageContext.setAttribute("aMap",map);

%>

${aList}<br/> <!--直接输出数组-->

${aList[0]}<br/> <!--按下标读取数组-->

${aList[2]}<br/> <!--按下标读取数组-->

${aMap}<br/> <!--直接输出映射-->

${aMap.shape}<br/> <!--按键读取映射-->

下面是在网页中输出的结果 🔻

[one, two, three]

one

three

{color=red, shape=square}

square

对象的展示

测试🔻

<%

class Student{

        private final String name = "Tom";

        private final String sex = "boy";

        @Override

        public String toString() {

            return name+" is a "+sex;

        }

}

Student student = new Student();

pageContext.setAttribute("aStudent",student);

%>

${aStudent}<br/>

下面是在网页中输出的结果 🔻

Tom is a boy

可以看出来EL对于对象的展示其实就是调用了toString()方法,包括集合也一样。如果这个对象没有重写toString()方法,那么机会调用父类toString()方法。比如父类是Object,那么就会输出hashcode。

对象的字段(属性)的获取

获取方式: ${object.field} 即可获取对象的字段(属性)

测试代码🔻

com.java.webtest.Student

package com.java.webtest;

public class Student {

    private String name = "Jack";

    public String getName() {

        return name;

    }

}

myTest.jsp

<%@ page import="com.java.webtest.Student" %>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>

<head>

    <title>myTest</title>

</head>

<body>

    <%

        Student s1 = new Student();

        pageContext.setAttribute("s1",s1);

    %>

    name = ${s1.name}<br/>

</body>

</html>

运行结果

name = Jack

⚠️ EL表达式获取对象字段(属性)是通过反射机制。${s1.name} 底层逻辑是将首字母"n"大写再在前面拼接一个"get",然后反射获取"getName"方法。所以对象必须提供字段的get方法,才能使用EL表达式 ${object.field} ,如果不写就会报错,或者你让get方法返回一个和相应字段无关的东西来证明确实是调用了get方法得到值的。

EL的运算

运算类型 描述

算术型 加+ 减- 乘* 除/、 div 取余% 、mod

逻辑型 and、&&、or、||、!、not

关系型 ==、eq、!=、ne、<、lt、>、gt、<=、le、>=、ge

empty 判断一个值是否为null或者为empty,如${empty ""} 返回值为true

三目运算 expression ? valueA : valueB 若expression为true返回valueA否则返回valueB

做一个测试 🔻

<%

    class Person{

        private int id;

        private String sex;

        public Person(int id,String sex){ this.id = id; this.sex = sex; }

        @Override

        public boolean equals(Object o) { return id == ((Person) o).id; }

    }

    Person p1 = new Person(777,"boy");

    Person p2 = new Person(777,"girl");

    Person p3 = new Person(666,"boy");

    pageContext.setAttribute("p1",p1);

    pageContext.setAttribute("p2",p2);

    pageContext.setAttribute("p3",p3);

%>

1 + 2 = ${1 + 2}<br/>

1 - 2 = ${1 - 2}<br/>

3 * 3 = ${3 * 3}<br/>

10 / 3 = ${10 / 3}<br/>

10 div 3 = ${10 div 3}<br/>

10 % 3 = ${10 % 3}<br/>

10 mod 3 = ${10 mod 3}<br/>

true and false -> ${true and false}<br/>

true && false ->${true && false}<br/>

true or false -> ${true or false}<br/>

true || false -> ${true || false}<br/>

not true -> ${not true}<br/>

!true -> ${!true}<br/>

666 == 666 -> ${666 == 666}<br/>

p1 == p2 -> ${p1 == p2}<br/>

p1 == p3 -> ${p1 == p3}<br/>

"ABCDEFG" == "abcdefg" -> ${"ABCDEFG" == "abcdefg"}<br/>

"ABCDEFG" == "ABCDEFG" -> ${"ABCDEFG" == "ABCDEFG"}<br/>

"ABCDEFG" eq "abcdefg" -> ${"ABCDEFG" eq "abcdefg"}<br/>

"ABCDEFG" eq "ABCDEFG" -> ${"ABCDEFG" eq "ABCDEFG"}<br/>

"ABCDEFG" != "abcdefg" -> ${"ABCDEFG" != "abcdefg"}<br/>

"ABCDEFG" != "ABCDEFG" -> ${"ABCDEFG" != "ABCDEFG"}<br/>

"ABCDEFG" ne "abcdefg" -> ${"ABCDEFG" ne "abcdefg"}<br/>

"ABCDEFG" ne "ABCDEFG" -> ${"ABCDEFG" ne "ABCDEFG"}<br/>

10 < 3 -> ${10 < 3}<br/>

10 lt 3 -> ${10 lt 3}<br/>

10 > 3 -> ${10 > 3}<br/>

10 gt 3 -> ${10 gt 3}<br/>

10 <= 3 -> ${10 <= 3}<br/>

10 le 3 -> ${10 le 3}<br/>

10 >= 3 -> ${10 >= 3}<br/>

10 ge 3 -> ${10 ge 3}<br/>

empty "" -> ${empty ""}<br/>

empty null -> ${empty null}<br/>

empty 666 -> ${empty 666}<br/>

55 > 60 ? "you pass!" : "you fail..." -> ${55 > 60 ? "you pass!" : "you fail..."}<br/>

页面的输出结果🔻

1 + 2 = 3

1 - 2 = -1

3 * 3 = 9

10 / 3 = 3.3333333333333335

10 div 3 = 3.3333333333333335

10 % 3 = 1

10 mod 3 = 1

true and false -> false

true && false ->false

true or false -> true

true || false -> true

not true -> false

!true -> false

666 == 666 -> true

p1 == p2 -> true

p1 == p3 -> false

"ABCDEFG" == "abcdefg" -> false

"ABCDEFG" == "ABCDEFG" -> true

"ABCDEFG" eq "abcdefg" -> false

"ABCDEFG" eq "ABCDEFG" -> true

"ABCDEFG" != "abcdefg" -> true

"ABCDEFG" != "ABCDEFG" -> false

"ABCDEFG" ne "abcdefg" -> true

"ABCDEFG" ne "ABCDEFG" -> false

10 < 3 -> false

10 lt 3 -> false

10 > 3 -> true

10 gt 3 -> true

10 <= 3 -> false

10 le 3 -> false

10 >= 3 -> true

10 ge 3 -> true

empty "" -> true

empty null -> true

empty 666 -> false

55 > 60 ? "you pass!" : "you fail..." -> you fail...

我认为应该特别注意两点

两个整数相除的结果并不是整数

p1 == p2 -> true 和 "ABCDEFG" == "ABCDEFG" -> true。显然不同于Java,EL表达式重载了 == ,对象之间使用 == 比较的时候,并不是比较对象的引用变量(也就是对象地址或指针),而是使用了 equals(Object o) 方法。!= 比较对象也是同理,可以自己测试一下。

JSTL标签库

JSTL(Java server pages standarded tag library)是一个JSP标准标签库,它封装了JSP应用的通用核心功能。JSTL支持通用的、结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。 除了这些,它还提供了一个框架来使用集成JSTL的自定义标签。下文将阐述部分常用的JSTL标签。EL和JSTL核心标签库通常搭配使用效果最佳

使用前的准备

导入相应的jar包:standard.jar 和 jstl.jar

JSP页面引入标签库

<%@ taglib prefix="前缀" uri="功能范围路径" %>

功能范围 prefix uri

core c http://java.sun.com/jsp/jstl/core

i18n fmt http://java.sun.com/jsp/jstl/fmt_rt

sql sql http://java.sun.com/jsp/jstl/sql

xml x http://java.sun.com/jsp/jstl/xml

functions fn http://java.sun.com/jsp/jstl/function

⚠️ 如果在后面使用中出现 500错误页面,其中包含类似这样的信息:atrribute [value] does not accpet any expressions,有可能是uri的问题,可能需要换一个uri。uri不同版本功能有差别所以会导致一些错误。

标签使用语法

<prefix:tag attribute="value" ... >

...

</prefix:tag>

重要标签

🙌 免责声明:以下标签属性总结并不全面,只讲比较常用的属性;并且由于uri不同属性不同。具体内容请查看你导入的standard.jar

<c:tag>标签

使用标签前不要忘记导入标签,不过IDEA也会自动导入。核心标签按照功能可以分为👇

表达式操作: out、set、remove、catch

流程控制: if、choose、when、otherwise

迭代操作: forEach、forTokens

URL操作: import、param、url、redirect

<c:set>标签

属性 缺省 说明

value - 向域中存入的变量值

var - 向域中存入的变量名

scope page 指定存储在4个域中的哪一个

target - Java对象

property - Java对象的字段(属性)。因为使用的是反射技术,与前面EL表达式获取字段值同理:该字段必须有set方法

<c:out>标签

属性 缺省 说明

value - 需要显示出来的值

default - 如果value的值为null,则显示default的值

escapeXml true 是否转义xml字符。有些字符如&lt在xml中被认为是<,若要它的字面意思,就需要使用转移

案例 👇

com.java.testclass.Person

package com.java.testclass;

public class Person {

    private String name;

    private int age;

    public Person(String name, int age) {

        this.name = name;

        this.age = age;

    }

    @Override

    public String toString() {

        return name+" is "+age+" years old.";

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public int getAge() {

        return age;

    }

    public void setAge(int age) {

        this.age = age;

    }

}

JSTL-test.jsp

<%@ page import="com.java.testclass.Person" %>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt_rt" %>

<html>

<head>

    <title>JSTL-test</title>

</head>

<body>

<%

    pageContext.setAttribute("person1",new Person("Tom",18));

    pageContext.setAttribute("person2",null);

%>

<h6>********** set & out Test **********</h6>

<%--向域中存值--%>

<c:set var="fruit" value="apple"></c:set>

<c:set var="fruit" value="banana" scope="session"></c:set>

<%--设置Java对象的字段--%>

<c:set value="David" target="${person1}" property="name"></c:set>

<c:set target="${person1}" property="age">18</c:set><br>

<%--输出--%>

<c:out value="${fruit} is fruit." default="fruit is null!"></c:out><br>

person1 : ${person1}<br>

person2 : <c:out value="${person2}" default="person2 is null!"></c:out><br>

<c:out value="&lt==when escapeXml is true==&gt"></c:out><br>

<c:out value="&lt==when escapeXml is false==&gt" escapeXml="false"></c:out><br>

</body>

</html>

结果

********** set & out Test **********

apple is fruit.

person1 : David is 18 years old.

person2 : person2 is null!

&lt==when escapeXml is true==&gt

<==when escapeXml is false==>

<c:if>标签

属性 缺省 说明

test - if 的条件表达式

var - 定义一个变量存储if 条件表达式的结果

scope page var变量的JSP范围

<c:choose>标签

属性 缺省 说明

test 无 如果表达式的结果为true,则执行体内容,false则相反

<c:choose>

    <c:when test="boolean表达式">

    </c:when>

    <c:otherwise>

    </c:otherwise>

</c:choose>

<c:forEach>标签

用于遍历集合元素

属性 缺省 说明

var - 遍历用的循环变量

items - 被遍历的集合对象

varStatus - 存放本轮循环变量的相关参数

begin 0 遍历起点下标

end 最后元素下标 遍历终点下标

step 1 每次迭代的间隔数

直接看例子 👇

<%

    int[] arr = {100,200,300,400,500,600,700,800,900,1000};

    pageContext.setAttribute("arr",arr);

%>

<h6>********** process control Test **********</h6>

foreach arr

<c:forEach items="${arr}" var="it" begin="1" end="7" step="2" varStatus="status">

    <c:if test="${status.count==1}">

        from ${status.begin} to ${status.end} by step = ${status.step}<br>

    </c:if>

    arr[${status.index}] = ${it} , count = ${status.count}<br>

</c:forEach>

结果

********** process control Test **********

foreach arr from 1 to 7 by step = 2

arr[1] = 200 , count = 1

arr[3] = 400 , count = 2

arr[5] = 600 , count = 3

arr[7] = 800 , count = 4

从结果count属性并不是与index属性关联的值,index是数组的下标,count仅作为循环的计数器。

<fmt:tag>标签

<fmt:formatDate>标签

该标签用于格式化输出Date类型变量,比较常用

属性 缺省 说明

value - 用于指定被格式化对象

pattern - 格式化的模式,与SimpleDateFormat的参数设置一样

var - 指定产生的格式化字符串所存放的变量,若不指定则直接输出在页面中

scope page 指定var变量的存储域

type date 说明value对象包含时间或包含日期还是两者兼具。取值为date/time/both

<fmt:parseDate>标签

<fmt:formatDate>的逆向过程,用于将指定字符串转化为日期类型

属性 说明

value 用于指定被转化的字符串

pattern 指定解析字符串的格式

var 指定生成的时间对象所存放的变量

请看测试代码 👇

<%

    pageContext.setAttribute("now",new Date());

%>

<h6>******************** fmt Test ********************</h6>

before formatting : ${now}. <br>

<fmt:formatDate value="${now}" pattern="yyyy-MM-dd" var="parse_date"></fmt:formatDate>

after formatting  : ${parse_date}. <br>

<fmt:parseDate value="${parse_date}" var="gotten_date" pattern="yyyy-MM-dd"></fmt:parseDate>

date get from string : ${gotten_date}. <br>

结果

******************** fmt Test ********************

before formatting : Sat Mar 13 23:03:16 CST 2021.

after formatting : 2021-03-13.

date get from string : Sat Mar 13 00:00:00 CST 2021

❕ 注意第一个日期与第三个日期的差别,这是由于第一次转换的时候丢失了时间信息

<fmt:formatNumber>标签

USB Microphone https://www.soft-voice.com/

Wooden Speakers  https://www.zeshuiplatform.com/

亚马逊测评 www.yisuping.cn

深圳网站建设www.sz886.com

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容