JSP-07使用EL和JSTL简化JSP
一、学习目标
- 掌握EL表达式的使用
- 掌握常用JSTL标签的使用
二、EL表达式
为什么要使用EL表达式?
在JSP中编写Java脚本的弊端
- 程序结构复杂
- 可读性差
- 不易维护
<p>书名:<%= book.getTitle() %></p>
<p>图书类型:<%= book.category.getCategoryName() %></p>
<p>出版社:<%= book.publisher.getPublisherName() %></p>
使用EL表达式可以极大的简化JSP代码
<p>书名:${book.title}</p>
<p>图书类型:${book.category.name}</p>
<p>出版社:${book.publisher.name}</p>
2.1初识EL表达式
什么是EL表达式
Expression Language(表达式语言)
EL的功能
1.替代JSP页面中访问数据时的复杂编码
2.执行表达式
EL的特点
1.自动转换类型
2.使用简单
2.2EL表达式语法
前提:web.xml配置文件的头部必须是3.0或者以上版本
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
语法:
${表达式}
通过变量名获取变量值
<% request.setAttribute("username","张三"); %>
<p>用户名:${username}</p>
<p>用户名:${requestScope.username}</p>
若省略作用域,将按照page → request → session → application
作用域的顺序依次查找,找到即返回,找不到返回null。
EL表达式对应JSP作用域的名称
属性范围 | EL表达式中的名称 | 属性范围 | EL表达式中的名称 |
---|---|---|---|
page | pageScope | session | sessionScope |
request | requestScope | application | applicationScope |
EL表达式中的对象元素和集合元素
通过操作符获取对象的属性值
点操作符
(推荐使用)
${user.name}
[ ]操作符
${user["name"]}
获取List集合中的值
${ listName[0] }
${ listName[1] }
获取Map集合中的值
${ map.keyName }
${ map["keyName"] }
使用EL表达式输出用户信息
使用EL表达式获取存储于Map中的用户信息示例:
<%
Map<String,String> map = new HashMap<String,String>();
map.put("name","张三");
map.put("hobby","打羽毛球");
request.setAttribute("user",map);
%>
<p>用户名:${user.name}</p>
<p>用户爱好:${user["hobby"]}</p>
运行效果
用户名:张三
用户爱好:打羽毛球
2.3EL表达式使用算数运算符
算术运算符 | 说明 | 示例 | 结果 |
---|---|---|---|
+ | 加 | ${10+5} | 15 |
- | 减 | ${10-5} | 5 |
* | 乘 | ${10*5} | 50 |
/ 或 div | 除 | ${10/5}或${10 div 5} | 2 |
% 或 mod | 取模 | ${10%5}或${10 mod 5} | 0 |
注意事项:EL表达式中“+”运算符两侧的内容如果无法自动转化为数字类型,该表达式将会抛出异常
2.4EL表达式使用关系运算符
算数运算符 | 说明 | 示例 | 结果 |
---|---|---|---|
== 或eq | 等于 | ${23==5}或${23 eq 5 ${"a"=="a"}或${"a" eq "a"} | false true |
!= 或ne | 不等于 | ${23!=5}或${23 ne 5} | true |
< 或lt | 小于 | ${23<5}或${23 lt 5} | false |
> 或gt | 大于 | ${23>5}或${23 gt 5} | true |
<= 或le | 小于等于 | ${23<=5}或${23 le 5} | false |
>= 或ge | 大于等于 | ${23>=5}或${23 ge 5} | true |
2.5EL表达式使用逻辑运算符和Empty运算符
算数运算符 | 说明 | 示例 | 结果 |
---|---|---|---|
&& 或and | 逻辑与 | 如果A为true,B为false,则KaTeX parse error: Expected '}', got '&' at position 4: {A &̲& B}或{A and B} | false |
|| 或or | 逻辑或 | 如果A为true,B为false,则 A ∣ ∣ B 或 {A || B}或 A∣∣B或{A or B} | true |
! 或not | 逻辑非 | 如果A为true,则 ! A 或 {!A}或 !A或{not A} | false |
Empty运算符
Empty运算符是一个前缀操作符,用于检测一个变量是否为空 :
<% request.setAttribute("username","张明"); %>
${empty username} // 返回 false
${not empty username} // 返回 true
${! empty username} // 返回 true
2.6EL表达式的隐式对象
可以直接从不同作用域和请求中读取信息
2.6.1作用域访问对象
对象名称 | 说明 |
---|---|
pageScope | 与page作用域中的属性相关联的Map类 |
requestScope | 与request作用域中的属性相关联的Map类 |
sessionScope | 与session作用域中的属性相关联的Map类 |
applicationScope | 与application作用域中的属性相关联的Map类 |
如果指定作用域,EL表达式将在该作用域内查找变量值
如果不指定作用域,EL表达式将按page → request → session → application
的顺序依次查找变量值
2.6.2参数访问对象
对象名称 | 说明 |
---|---|
param | 按照参数名称访问单一请求值的Map对象 |
paramValues | 按照参数名称访问数组请求值的Map对象 |
2.6.3JSP隐式对象
对象名称 | 说明 |
---|---|
pageContext | 提供对页面信息和JSP内置对象的访问 |
2.6.4首部访问对象
对象名称 | 说明 |
---|---|
header | 按名称存储请求头主要值的Map类 |
headerValues | 将请求头的所有值作为String数组存储的Map类,返回指定请求头的所有值组成的字符串数组 |
cookie | 按名称存储请求附带的cookie的Map类 |
2.6.5初始化参数访问对象
对象名称 | 说明 |
---|---|
initParam | 按名称存储 Web 应用程序上下文初始化参数的Map类 |
2.6.6使用EL表达式改造图书详情页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<meta name="Robots" content="index,follow" />
<title>"第三波书店"-网上书店</title>
<link href="css/global.css" rel="stylesheet" type="text/css" />
<link href="css/channel.css" rel="stylesheet" type="text/css" />
<link href="css/answer.css" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- 头部 begin -->
<%@ include file="common/header.jsp"%>
<!-- 头部 end -->
<div id="container">
<!--left content-->
<!--左侧分类菜单 begin-->
<%@ include file="common/leftMenu.jsp"%>
<!--左侧分类菜单 end-->
<div class="book_view">
<c:if test="${empty requestScope.book }">
<h1 class="b_title">暂无该书籍的详情信息!</h1>
</c:if>
<c:if test="${not empty requestScope.book}">
<h1 class="b_title">${requestScope.book.title}</h1>
<div class="b_exa">
<span class="book_group">丛书名:${requestScope.book.title}</span>
<span class="book_status">点击量:${requestScope.book.clicks} <span><a href="#">放入书架</a></span> <a href="#">什么是书架?</a></span>
</div>
<!--book basic start-->
<dl class="put_book">
<dt>
<img src="images/BookCovers/${requestScope.book.isbn}.jpg" width="200" height="275" alt="${requestScope.book.title}" />
<div class="chakan"><img src="images/zoom.gif" /> <a class="gray878787a" href="#" name="bigpicture">点击查看大图</a></div>
</dt>
<dd>
<div id="book_editor">
作 者: ${requestScope.book.author} 著<br />
出 版 社: ${requestScope.book.publisher.name}
</div>
<ul id="book_attribute">
<li>出版时间:${requestScope.book.publishDate}</li>
<li>ISBN: ${requestScope.book.isbn}</li>
<li>库存:(${requestScope.book.sumStock})本</li>
</ul>
<div id="book_categroy">
所属分类: <a href="javascript:void(0)" target="_blank" class="blue12a">图书</a> >>
<a href="javascript:void(0)" target="_blank" class="blue12a"> ${requestScope.book.categorie.name}</a>
<div id="book_price">
<span class="gray87">
定价:<span class="del">¥${requestScope.book.unitPrice}</span></span>
<span class="red">
当当价:¥<b>
<fmt:formatNumber type="number" value="${requestScope.book.unitPrice * 0.6 }" pattern="0.00" maxFractionDigits="2"/></b></span>
折扣:<span class="redc30">6折</span>
节省:¥<fmt:formatNumber type="number" value="${requestScope.book.unitPrice-(requestScope.book.unitPrice * 0.6) }" pattern="0.00" maxFractionDigits="2"/>
</div>
<div id="book_point">
<span >送积分:<span id="pointsTag" >${requestScope.book.unitPrice}</span></span> <a target="_blank" href="javascript:">积分说明</a> <br />
<a href="javascript:void(0)" id="btn_addCart" cart-id="${requestScope.book.id}"><img src="images/btn_goumai.gif"
onmouseover="this.src='images/btn_goumai_click.gif'"
onmouseout="this.src='images/btn_goumai.gif'" />
</a>
<a href="javascript:history.go(-1)">返回</a>
</div>
<div id="book_count">
顾客评分:<span id="book_id_15">5</span> 共有商品评论0条 <a href="#">查看评论摘要</a>
</div>
</dd>
</dl>
<!--book basic end-->
<!--book intro start-->
<dl class="book_intro">
<dt>内容简介</dt>
<dd>${requestScope.book.contentDescription}</dd>
</dl>
<dl class="book_intro">
<dt>目录</dt>
<dd>${requestScope.book.toc}</dd>
</dl>
<!--book intro end-->
<!--recommed start-->
<div class="comm_answer">
<!--review head start-->
<div id="div_product_reviews">
<div class="total_comm">
<div class="comm_title">
<h2>商品评论 共<em>814</em>条
<span class="look_comm"> (<a href="javascript:" name='reviewList' target='_blank'>查看所有评论</a>)</span></h2>
</div>
<div class="total_body">
<div class="people_average">
<div class="average_left"><p>购买过的顾客平均评分</p><span class="a_red28b pd">4</span><span class="red_bold">星半</span><img src='images/star_red.gif' /><img src='images/star_red.gif' /><img src='images/star_red.gif' /><img src='images/star_red.gif' /><img src='images/star_redgray_big.gif' />
</div>
<span class="span_jt" id="div_window_star"><input class="button_down1" value="" type="button" /></span>
</div>
<div id="div_product_summary" >
<div class="people_heart">心情指数:<em>249</em>人 开心
<span id="div_emotion_hover" >
<input class="button_down1" type="button" />
</span>
</div>
<div id="Div1" class="people_read" >阅读场所:<em>180</em>人 床上
<span id="div_location_hover" >
<input class="button_down1" type="button" />
</span>
</div>
</div>
<div class="write_comm">
<a id="reviewTipa" href="#"><img src="images/button_write_comm.gif" border="0" title="写评论" /></a>
</div>
</div>
</div>
</div>
<!--review head end-->
<!--the one reviews start-->
<div class="comm_list">
<h3>
<img src="images/label_1.gif" title="精彩评论" /><a href="javascript:" target="_blank" name="reviewDetail">非常不错的一本书</a>
<span>发表于 2009-04-29 22:46</span>
</h3>
哦耶,终于拿到书了。 <br/>实物比照片显示的要漂亮,颜色是看上去很舒服的红色。 <br/>书很厚,是塑封的,里面有两张挂图,一张标准穴位图,一张足部反射区图,还有一张配套的光盘,用DVD机试了一下,是中里老师讲的。嗯,
</div>
<!--the one reviews end-->
</div>
<!--recommed end-->
</c:if>
</div>
<!--right content end-->
</div>
<!-- 底部 begin-->
<%@ include file="common/footer.jsp"%>
<!-- 底部 end -->
</body>
</html>
三、JSTL
为什么使用JSTL
问题: 使用EL表达式可以简化JSP页面编码,但是页面中的逻辑控制和循环控制该怎么处理?
分析:
1. EL表达式封装了数据访问的功能,但并不提供逻辑控制功能
2. JSTL标签库则封装了逻辑控制、循环控制以及数据格式化等功能
3. 二者结合使用才能完整实现动态页面的开发需求
3.1什么是JSTL
JSTL(Java server pages standarded tag library
,即JSP标准标签库)是由JCP(Java community Proces)所制定的标准规范,它主要提供给Java Web开发人员一个标准通用的标签库,并由Apache的Jakarta小组来维护。开发人员可以利用这些标签取代JSP页面上的Java代码,从而提高程序的可读性,降低程序的维护难度。
优点
- 不用嵌入Java代码就可以实现JSP页面逻辑控制
- 配合EL表达式,方便的实现JSP页面编码
- 代码简洁
3.2引入JSTL
在工程中引用JSTL的jar文件
第一步:在maven的pom.xml中添加依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
第二步:在JSP页面使用taglib指令导入标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
uri:指定要引入的标签库
prefix:为引入的标签库指定别名,核心标签库一般使用 “c”
第三步:使用标准标签库
<c:标签名>
3.2JSP中使用JSTL标准标签库
3.2.1通用标签库-out标签
作用: 用于输出表达式结果,类似于JSP中的表达式<%=%>
语法:
<c:out value="<string>" default="<string>" escapeXml="<true|false>"/>
属性说明:
value: 输出表达式的运算结果,可以通过EL表达式来获取
default: value属性的值为空时输出的默认值
escapeXml : 表示是否转换<、 >、‘、” 、&等特殊字符
使用out标签进行输出示例:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
pageContext.setAttribute("content1",null);
pageContext.setAttribute("content2","<a href='www.qq.com'>腾讯网</a>");
%>
<!--演示default属性-->
<p><c:out value="${content1}" default="Empty" /></p>
<!--演示escapeXml属性-->
<p>${content2}</p>
<p><c:out value="${content2}" escapeXml="false" /></p>
<p><c:out value="${content2}" /></p>
运行效果:
3.2.2通用标签库-set标签
作用: 设置作用域变量的值或属性值
语法:
<c:set var="<string>" value="<string>" scope="<string>" target="<string>" property="<string>" />
- var: 设置的变量名
- value: 要存储的变量值
- scope: 变量的作用域,包括page、request、session、application
- target: 要设置的JavaBean对象或Map对象。可以使用EL表达式
- property: 在JavaBean对象或Map对象情况下,要设置的对象属性或key
注意: 如果指定了target属性,则property属性也需要被指定
set标签的两种使用方式
将value值存储到范围为scope的变量var中
将value值设置到对象的属性中
set标签的使用
创建User实体类
public class User implements Serializable {
private static final long serialVersionUID = 6157531094355458440L;
private String username;
private String password;
private String fullName;
//省略setter和getter方法
}
使用set标签为User对象设值
<%@ page import="com.bookshop.entity.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>set标签</title>
</head>
<body>
<%
User user = new User();
request.setAttribute("user", user);//存储到request作用域中
%>
<p><c:out value="${user.fullName}" default="No fullName"/></p>
<p><c:set target="${user}" property="fullName" value="Aiden"/></p>
<p><c:out value="${user.fullName}" default="No fullName"/></p>
</body>
</html>
运行效果
3.2.3通用标签库-remove标签
作用: 用于移除指定作用域内的指定变量
语法:
<c:remove var="<string>" scope="<string>"/>
var: 待移除的变量名
scope: 变量所在作用域
使用remove标签移除变量
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="username" scope="page" value="Jerry"/>
<p>当前username的值:username=<c:out value="${username}" default="No Username"/></p>
<c:remove var="username" scope="page"/>
<p>移除属性后:username = <c:out value="${username}" default="No Username" /></p>
运行结果:
3.2.4条件标签库-if标签
作用: 用于实现逻辑控制,与Java中的if关键字类似
语法:
<c:if test="condition" var="varName" scope="scope">
主体内容
</c:if>
- test: 判断条件,当执行结果为true时,执行if标签中的内容。可以使用EL表达式
- var: 定义变量,存放表达式的执行结果
- scope: 变量所在的作用域,包括page、request、session、application
使用if标签实现分页功能示例:
<div style="margin: 10px 50px">
<c:set var="pageIndex" value="${requestScope.bookModel.pageIndex}"></c:set>
<c:set var="totalPage" value="${requestScope.bookModel.totalPage}"></c:set>
<c:set var="totalCount" value="${requestScope.bookModel.totalCount}"></c:set>
<c:if test="${pageIndex > 1}">
<a href="BookServlet?pageIndex=1">首 页</a>
<a href="BookServlet?pageIndex=${pageIndex-1}">上一页</a>
</c:if>
<c:if test="${pageIndex < totalPage}">
<a href="BookServlet?pageIndex=${pageIndex+1}">下一页</a>
<a href="BookServlet?pageIndex=${totalPage}">尾 页</a>
</c:if>
<span>第 ${pageIndex} 页/共 ${totalPage} 页/共 ${totalCount} 条</span>
</div>
3.2.5条件标签库-choose标签
<c:choose>、<c:when>和<c:otherwise>标签
作用: 用于实现互斥关系的逻辑控制
语法:
<c:choose var="varName" scope="scope">
<!--test表达式条件满足时,执行标签内的主体内容-->
<c:when test="condition1">
主体内容
</c:when>
……
<!--所有when标签均不满足时,执行otherwise标签内容-->
<c:otherwise>
主体内容
</c:otherwise>
</c:choose>
when标签可以有多个
otherwise标签必须是choose标签中的最后一个标签
使用choose判断图书订单状态示例:
<c:choose>
<c:when test="${order.orderStatus==0}">订单待付款</c:when>
<c:when test="${order.orderStatus==1}">订单待发货</c:when>
<c:when test="${order.orderStatus==2}">订单配送中</c:when>
<c:when test="${order.orderStatus==3}">订单已送达,待签收</c:when>
<c:when test="${order.orderStatus==4}">订单已签收</c:when>
<c:when test="${order.orderStatus==5}">订单被拒收</c:when>
<c:otherwise>
订单已取消
</c:otherwise>
</c:choose>
3.2.6迭代标签库-forEach标签
作用: 遍历集合
语法:
<c:forEach items="collectionName" var="varName" begin="beginIndex" varStatus="varStatusName" end="endIndex" step="step">
主体内容
</c:forEach>
属性介绍:
- items:集合对象,可通过EL表达式获取
- var :集合元素遍历过程中,当前元素的引用
- varStatus :存放var属性引用元素的相关信息,如索引等
- begin :循环的开始位置,可省略,默认为0
- end :循环的结束位置,可省略,默认为集合最后位置
- step :循环的步长,可省略,默认为1
使用forEach标签遍历图书信息
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="f"%>
<ul>
<c:if test="${empty requestScope.bookModel.list }">
<a href="BookServlet"><h3>无数据?刷新试试^_^</h3></a>
</c:if>
<c:forEach items="${requestScope.bookModel.list}" var="b">
<li title="${b.title }">
<a href="BookServlet?operType=details&bookId=${b.id}">
<img src="images/BookCovers/${b.isbn }.jpg" width="108" height="125"></img>
</a>
<a href="BookServlet?operType=details&bookId=${b.id}">
<!--截取超过指定长度的字符串-->
<c:set var="title" value="${b.title}"></c:set>
<c:if test="${f:length(title) >5 }">
${f:substring(title,0,5) }...
</c:if>
<c:if test="${f:length(title) <=5 }">
${title}
</c:if>
</a>
</li>
</c:forEach>
</ul>
使用forEach标签遍历Map
使用forEach遍历读取存储城市以及所属省份的Map
在JSP中引入Map相关包
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
创建一个Map,将省份信息存入Map
<%
Map<String,String> map=new HashMap<String,String>();
map.put("武汉", "湖北省");
map.put("洛阳", "河南省");
map.put("广州", "广东省");
map.put("大理", "云南省");
request.setAttribute("map", map);
%>
使用forEach标签遍历Map
<c:forEach var="entry" items="${map}">
<p>${entry.key} ${entry.value}</p>
</c:forEach>
运行结果:
四、JSTL中使用自定义函数
1、在utils包中自定义DateUtil工具类,注意定义的方法必须为静态方法
package com.bookshop.utils;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* 日期转换工具类
* @author Aiden
*/
public class DateUtil {
/**
* LocalDateTime转字符串
* @param localDateTime
* @param pattern 转换格式
* @return String
*/
public static String dateToString(LocalDateTime localDateTime,String pattern) {
String dateTime = DateTimeFormatter.ofPattern(pattern).format(localDateTime);
return dateTime;
}
//测试方法:
public static void main(String[] args) {
String s = dateToString(LocalDateTime.now(),"yyyy-MM-dd");
System.out.println(s);
}
}
在maven项目的
src\main\webapp\WEB-INF
目录下创建一个函数模板文件:myFunction.tld
myFunction.tld文件定义:
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>JSTL1.2 functions library</description>
<display-name>JSTL自定义函数</display-name>
<tlib-version>1.2</tlib-version>
<short-name>myFun</short-name>
<uri>http://java.sun.com/jsp/jstl/functions</uri>
<function>
<!--描述-->
<description>转换时间类型为字符串</description>
<!--函数名-->
<name>dateToString</name>
<!--函数功能类-->
<function-class>com.bookshop.utils.DateUtil</function-class>
<!--函数签名:描述函数参数和返回类型-->
<function-signature>java.lang.String dateToString(java.time.LocalDateTime,java.lang.String))
</function-signature>
<!--函数示例-->
<example>${myFun:dateToString(localDateTime,pattern)}</example>
</function>
</taglib>
页面中引入模板与使用 (
<%@taglib prefix="myFun" uri="/WEB-INF/myFunction.tld" %>
)
<%@ page import="java.util.Date" %>
<!--在页面引入核心库-->
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fm" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@taglib prefix="fun" uri="http://java.sun.com/jsp/jstl/functions" %>
<!--在页面引入自定义函数库-->
<%@taglib prefix="myFun" uri="/WEB-INF/myFunction.tld" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSTL使用自定义函数</title>
</head>
<body>
<%-- 判断page是否为空--%>
<c:if test="${empty requestScope.page}">
暂无数据
</c:if>
<c:if test="${not empty requestScope.page}">
<%--循环遍历page的dataList属性--%>
<c:forEach var="book" items="${requestScope.page.dataList}">
<p>完整书名:${book.title}</p>
<p>截取15位字符:${fun:substring(book.title,0 ,15 )}......</p>
<p>自定义函数转换:${myFun:dateToString(book.publishDate,'yyyy年MM月dd日')}</p>
<hr>
</c:forEach>
</c:if>
<hr>
<%
request.setAttribute("date", new Date());
%>
<p>
<fm:formatDate value="${date}" pattern="yyyy年MM月dd日"></fm:formatDate>
</p>
</body>
</html>
总结
思维导图:
学习讨论群: 617530501