重学SpringBoot系列之整合静态资源与模板引擎
- webjars与静态资源
- spring boot静态资源
- favicon.ico图标
- 欢迎页面
- 使用WebJars管理css&js
- 1.pom中引入依赖
- 2.访问引入的js文件
- 自动检测依赖的版本
- 测试
- 模板引擎选型与未来趋势
- java web开发经历的几个阶段
- jsp开发阶段
- 使用java模板引擎
- 前端工程化
- java模板引擎的选型。
- Thymeleaf:
- 最后
- java web开发经历的几个阶段
- web应用开发之整合jsp
- 通过Maven坐标集成jsp
- 配置JSP查找位置
- 代码测试
- 运行方法测试
- web应用开发之整合freemarker
- Freemarker简介
- 整合
- 代码测试
- web应用开发之整合thymeleaf
- Thymeleaf简介
- 准备工作-IDEA设置
- 集成
- Hello ThymeLeaf
- thymeleaf基础语法讲解
- 基础语法
- 变量表达式 ${}
- 选择变量表达式 *{}
- 链接表达式 @{}
- 其它表达式
- 迭代循环
- 条件判断
- 基础语法
- thymeleaf内置对象与工具类
- 内置对象
- 常用的工具类:
- 公共片段(标签)与内联js
- 片段表达式(标签) ~{}
- 多种片段组合方式
- 内联语法
webjars与静态资源
spring boot静态资源
静态资源目录
SpringBoot默认配置下,提供了以下几个静态资源目录:
代码语言:javascript复制/static: classpath:/static/
/public: classpath:/public/
/resources: classpath:/resources/
/META-INF/resources:classpath:/META-INF/resources/
当然,可以通过spring.resources.static-locations配置指定静态文件的位置。但是要特别注意,一旦自己指定了静态资源目录,系统默认的静态资源目录就会失效
。所以系统默认的就已经足够使用了,尽量不要自定义。
#配置静态资源
spring:
resources:
#指定静态资源目录
static-locations: classpath:/mystatic/
favicon.ico图标
如果在配置的静态资源目录中有favicon.ico文件,SpringBoot会自动将其设置为应用图标。
欢迎页面
SpringBoot支持静态和模板欢迎页,它首先在静态资源目录查看index.html文件做为首页,若未找到则查找index模板。
使用WebJars管理css&js
为什么使用 WebJars?
显而易见,因为简单。但不仅是依赖这么简单:
- 清晰的管理 web 依赖
- 通过 Maven, Gradle 等项目管理工具就可以下载 web 依赖
- 解决 web 组件中传递依赖的问题以及版本问题
- 页面依赖的版本自动检测功能
WebJars是将这些通用的Web前端资源打包成Java的Jar包,然后借助Maven工具对其管理,保证这些Web资源版本唯一性,升级也比较容易。关于webjars资源,有一个专门的网站https://www.webjars.org/,我们可以到这个网站上找到自己需要的资源,在自己的工程中添加入maven依赖,即可直接使用这些资源了。
1.pom中引入依赖
我们可以从WebJars官方查看maven依赖,如下图
例如:将bootstrap和jquery引入pom文件中
代码语言:javascript复制<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.5.0</version>
</dependency>
2.访问引入的js文件
在html内访问静态资源可以使用如下方式:
代码语言:javascript复制<script src="/webjars/jquery/3.5.1/jquery.min.js "></script>
<script src="/webjars/bootstrap/4.5.0/js/bootstrap.min.js"></script>
自动检测依赖的版本
如果使用 Spring 4.2 以上的版本,并且加入 webjars-locator 组件,就不需要在 html 添加依赖的时候填写版本。
代码语言:javascript复制<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
<version>0.30</version>
</dependency>
引入 webjars-locator 值后可以省略版本号:
代码语言:javascript复制<script src="/webjars/jquery/jquery.min.js "></script>
<script src="/webjars/bootstrap/js/bootstrap.min.js"></script>
注意:只能去掉版本号,好处是:当你升级webjar版本的时候,就不用每个引入webjar的文件都修改一遍版本号。
简单来说,webjars可以统一的以jar包的形式管理前端的资源,这样就省去了下载前端资源文件,放到静态资源目录static目录下面的麻烦事
并且想替换版本的时候,不需要像之前删除掉旧版本的所有静态资源文件,再引进新版本那么麻烦,之前更改maven包管理里面的版本即可
测试
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
<link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.min.css">
</head>
<body>
<div class="container"><br/>
<div class="alert alert-success">
<strong>成功!</strong>bootstrap webjar 完美!
</div>
</div>
<script src="/webjars/jquery/jquery.min.js "></script>
<script src="/webjars/bootstrap/js/bootstrap.min.js"></script>
</body>
</html>
显示效果:bootstrap的alert-success
模板引擎选型与未来趋势
java web开发经历的几个阶段
jsp开发阶段
现在仍然有很多企业项目使用jsp开发。可以说jsp就是页面端的servlet,jsp文件糅合了三种元素:Java代码、动态的数据、HTML代码结构。从抽象层次来看,Java代码部分不仅用来组织数据,还被用来控制HTML页面结构。这样在层次划分上属于比较含糊不清的。当然企业可以通过规范的方式去限制,不允许在jsp页面写java代码,但这只是规范层面的事,实际怎样无法控制。
使用java模板引擎
在这个阶段就出现了freemarker、velocity这样的严格数据模型与业务代码分离的模板引擎。实现了严格的MVC分离,模板引擎的另外一个好处就是:宏定义或者说是组件模板,比jsp标签好用,极大的减少了重复页面组件元素的开发。另外,相对于jsp而言,模板引擎的开发效率会更高。我们都知道,JSP在第一次执行的时候需要转换成Servlet类,开发阶段进行功能调适时,需要频繁的修改JSP,每次修改都要编译和转换,那么试想一天中我们浪费在程序编译的时间有多少。
但是java模板引擎,仍然是使用的服务器端的渲染技术,也就是没有办法将html页面和后台服务层面全面解耦,这就要求前端工程师和后端工程师在同一个项目结构下工作,而且前端工程师及其依赖于后端的业务数据,页面无法脱离于后端请求数据在浏览器独立运行。
前端工程化
在ajax和nodejs相继出现之后,可以说为前端的发展带来了革命性的变化,前端可以做自己的工程化实践。这些新的前端技术通常是“所见即所得”,写完的代码可以直接在浏览器上查看,将前端后端的串行化工作模式转变为并行工作的模式。前端专注于布局、美化,后端专注于业务。专业的人越来越专业,工作效率也更高。
随着VUE、angularjs、reactjs的大行其道,开始实现真正的前后端分离技术。前端的工程师负责页面的美化与结构,后端工程师可以专注 于业务的处理。
java模板引擎的选型。
常见的模板引擎有Freemarker、Thymeleaf、Velocity等,下面我们就分别来说一下。
spring boot目前官方集成的框架只有freemarker和Thymeleaf,官方明确建议放弃velocity。很多人说thymeleaf是官方推荐使用的模板引擎,说实话我没找到这个说法的出处。
Thymeleaf:
Thymeleaf的最大优点也是他的最大的缺点,就是它使用静态html嵌入标签属性,浏览器可以直接打开模板文件,便于前后端联调。也就是贴近于“所见即所得”。但是也正是因为,thyme使用标签属性去放数据,也导致它的语法违反了程序员对于html的理解。另外Thymeleaf的性能一直为人所诟病。
Thymeleaf代码和下面freemarker对一个对象数组遍历的代码对比一下:
代码语言:javascript复制<tr th:each="item : ${users}">
<td th:text="${item.userId}"> </td>
<td th:text="${item.username}"> </td>
<td th:text="${item.password}"> </td>
<td th:text="${item.email}"> </td>
<td th:text="${item.mobile}"> </td>
</tr>
FreeMarker代码:
代码语言:javascript复制<#list users as item>
<tr>
<td>${item.userId}</td>
<td>${item.username}</td>
<td>${item.password}</td>
<td>${item.email}</td>
<td>${item.mobile}</td>
</tr>
</#list>
很明显FreeMarker更符合开发人员对于HTML的使用规范,将展示内容放在标签内,而不是作为标签属性存在。就冲这一点,就我个人而言,ThymeLeaf完全不在我的考虑范围之内。另外,ThymeLeaf2.0的性能非常差,为人所诟病,Thymeleaf3.0虽然有所改善,但是没有颠覆性的变化。
最后
综上,目前为止如果使用java模板引擎,我还是推荐freemarker。当然,我还有一个建议,去学LayUI等前端框架,或者去学vue、angularjs、reactjs,不要用纯java模板引擎,这些东西用的会越来越少。
上图是百度指数,技术的火爆程度一目了然!
web应用开发之整合jsp
通过Maven坐标集成jsp
JSP需要如下的三个依赖提供运行环境
- 内嵌的 tomcat容器,spring-boot-starter-web 包含了spring-boot-starter-tomcat ,所以不需要再单独引入。
- tomcat-embed-jasper 主要用来支持 JSP 的解析和运行。
- jstl ,提供给Java Web开发人员一个标准通用的标签库。开发人员可以利用这些标签取代JSP页面上写Java代码,从而提高程序的可读性,降低程序的维护难度。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring boot 内置tomcat jsp支持 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!--jsp页面使用jstl标签-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
配置JSP查找位置
我们需要通过配置告诉Spring Boot在进行页面渲染的时候,去哪里寻找JSP文件
代码语言:javascript复制spring:
mvc:
view:
suffix: .jsp
prefix: /WEB-INF/jsp/
debug: true
- spring.mvc.view.prefix 指明 jsp 文件在 webapp 下的哪个目录
- spring.mvc.view.suffix 指明 jsp以什么样的后缀结尾。一定是/WEB-INF/下的目录,否则后面我们打包会报错。
这个目录结构和配置文件指定的位置对应,一定不要放错了。
- 静态资源,如:图片放在resources/static目录下面
- jsp文件放在webapp.WEB-INF.jsp的下面
代码测试
代码语言:javascript复制@Controller
@RequestMapping("/template")
public class TemplateController {
@Resource
ArticleService articleService;
@GetMapping("/jsp")
public String index(String name, Model model) {
List<ArticleVO> articles = articleService.getAll();
model.addAttribute("articles", articles);
//模版名称,实际的目录为:src/main/webapp/WEB-INF/jsp/jsptemp.jsp
return "jsptemp";
}
}
jsptemp.jsp
文本代码如下
代码语言:javascript复制<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.min.css">
</head>
<body>
<table class="table">
<tr>
<td>作者</td>
<td>教程名称</td>
<td>内容</td>
</tr>
<c:forEach var="article" items="${articles}">
<tr class="text-info">
<td>${article.author}</td>
<td>${article.title}</td>
<td>${article.content}</td>
</tr>
</c:forEach>
</table>
<img src="/image/jsp.png">
<script src="/webjars/jquery/jquery.min.js "></script>
<script src="/webjars/bootstrap/js/bootstrap.min.js"></script>
</body>
运行方法测试
访问:http://localhost:8888/template/jsp,因为jsp对jar运行的方式支持不好,所以要一一进行测试,结果如下:
- 使用IDEA启动类启动测试,没有问题
- 使用spring-boot:run -f pom.xml测试,没有问题(maven启动)
- 打成jar包通过java -jar方式运行,页面报错
- 打成war包,运行于外置的tomcat,没有问题
所以,目前无法用jar包的形式运行jsp应用,至少我没有实验成功。
web应用开发之整合freemarker
Freemarker简介
FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写。一般对FreeMarker第一印象是用来替代JSP的,但是与JSP 不同的是FreeMarker 模板可以在 Servlet容器之外使用。可以使用它们来生成电子邮件、 配置文件、 XML 映射等。或者可以直接生成HTML文件,以及其他的文件,用来做代码自动生成的工具。
Freemarker作为页面模板引擎的核心能力在于,将以HTML为基础的模板中的相关语法占位符用数据进行填充,填充之后形成可以被浏览器渲染的HTML文件
整合
首先通过maven坐标的方式将freemarker引入到项目中来,因为freemarker是Spring Boot父项目支持的模板引擎,所以不用加版本号,版本由父项目统一管理
代码语言:javascript复制<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
在application.yml全局配置文件中进行如下的配置
代码语言:javascript复制spring:
freemarker:
cache: false # 缓存配置 开发阶段应该配置为false 因为经常会改
suffix: .ftl # 模版文件后缀名
charset: UTF-8 # 文件编码
template-loader-path: classpath:/templates/
如果没有,新建static和templates文件夹
代码测试
我们这里只做一个简单的测试,测试内容是:将article数据从数据库表里面查询出来,并将查询结果List返回给前端FreeMarker模板页面,进行数据填充。
代码语言:javascript复制import com.zimug.boot.launch.model.ArticleVO;
import com.zimug.boot.launch.service.ArticleService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.util.List;
@Controller
@RequestMapping("/template")
public class TemplateController {
@Resource
ArticleService articleService;
@GetMapping("/freemarker")
public String index(Model model) {
List<ArticleVO> articles = articleService.getAll();
model.addAttribute("articles", articles);
//模版名称,实际的目录为:resources/templates/fremarkertemp.ftl
return "freemarkertemp";
}
}
FreeMarker模板页面,核心内容在于<#list articles as article>进行列表数据遍历。(其他内容如:HTML、webjars都不是本节需要关注的核心内容)
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<table class="table">
<tr>
<td>作者</td>
<td>教程名称</td>
<td>内容</td>
</tr>
<#list articles as article>
<tr>
<td>${article.author}</td>
<td>${article.title}</td>
<td>${article.content}</td>
</tr>
</#list>
</table>
</div>
<script src="/webjars/jquery/jquery.min.js "></script>
<script src="/webjars/bootstrap/js/bootstrap.min.js"></script>
</body>
</html>
FreeMarker在线手册
web应用开发之整合thymeleaf
Thymeleaf简介
Thymeleaf 是一个服务器端 Java 模板引擎,能够处理 HTML、XML、CSS、JAVASCRIPT 等模板文件。Thymeleaf 模板可以直接当作静态原型来使用,它主要目标是为开发者的开发工作流程带来优雅的自然模板,也是 Java 服务器端 HTML5 开发的理想选择
准备工作-IDEA设置
在开始使用ThymeLeaf作为模板引擎进行页面开发之前,我们有必要对IDEA进行一些设置。这些设置帮助IDEA更好的识别ThymeLeaf语法,增强我们的开发体验
- 安装ThymeLeaf插件,并使其生效(在绝大多数的IDEA版本该插件都是默认安装并生效的)
- 去掉变量表达式识别检查,会造成变量红色下划线,影响开发体验
集成
使用Maven坐标将thymeleaf引入到项目中
代码语言:javascript复制<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
对thymeleaf模板进行配置
代码语言:javascript复制spring:
thymeleaf:
cache: false # 启用缓存:建议生产开启
check-template-location: true # 检查模版是否存在
enabled: true # 是否启用
encoding: UTF-8 # 模版编码
excluded-view-names: # 应该从解析中排除的视图名称列表(用逗号分隔)
mode: HTML5 # 模版模式
prefix: classpath:/templates/ # 模版存放路径
suffix: .html # 模版后缀
Hello ThymeLeaf
例子完成之后,项目代码结构如下:
查询一个articles文章列表,并返回模板名称,由Spring根据名称找到模板进行页面渲染
代码语言:javascript复制import com.zimug.boot.launch.model.ArticleVO;
import com.zimug.boot.launch.service.ArticleService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.util.List;
@Controller
@RequestMapping("/template")
public class TemplateController {
@Resource
ArticleService articleService;
@GetMapping("/thymeleaf")
public String index(Model model) {
List<ArticleVO> articles = articleService.getAll();
model.addAttribute("articles", articles);
//模版名称,实际的目录为:resources/templates/thymeleaftemp.html
return "thymeleaftemp";
}
}
新建thymeleaf模板页面:thymeleaftemp.html。
- 注意这个xmlns:th属性是一定要添加的。
- 注意:th:each是thymelaef,其核心功能是集合遍历
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<table class="table">
<tr>
<td>作者</td>
<td>教程名称</td>
<td>内容</td>
</tr>
<tr th:each="item : ${articles}">
<td th:text="${item.author}"></td>
<td th:text="${item.title}"></td>
<td th:text="${item.content}"></td>
</tr>
</table>
</div>
<script src="/webjars/jquery/jquery.min.js "></script>
<script src="/webjars/bootstrap/js/bootstrap.min.js"></script>
</body>
</html>
thymeleaf基础语法讲解
基础语法
变量表达式 ${}
使用方法:直接使用th:xx = “${}” 获取对象属性 。例如:articles是一个集合,集合中的元素就是一个对象,articles[0]表示集合中第一个对象
代码语言:javascript复制<div th:text="hello"></div>
<form id="articleForm">
<input id="id" name="id" th:value="${articles[0].id}"/>
<input id="author" name="author" th:value="${articles[0].author}"/>
<input id="content" name="content" th:value="${articles[0].content}"/>
</form>
选择变量表达式 *{}
使用方法:首先通过th:object 获取对象,然后使用th:xx = "*{}"获取对象属性。显示效果和上面的例子是一样的。
代码语言:javascript复制<form id="articleForm" th:object="${articles[0]}">
<input id="id" name="id" th:value="*{id}"/>
<input id="author" name="author" th:value="*{author}"/>
<input id="content" name="content" th:value="*{content}"/>
</form>
链接表达式 @{}
使用方法:通过链接表达式@{}直接拿到应用路径,然后拼接静态资源路径。例如:
代码语言:javascript复制<link rel="stylesheet" th:href="@{/webjars/bootstrap/css/bootstrap.min.css}">
<script th:src="@{/webjars/jquery/jquery.min.js} "></script>
<script th:src="@{/webjars/bootstrap/js/bootstrap.min.js}"></script>
html页面实际引入效果如下(这种方式会将webjars的版本号暴露出来,一定程度上造成安全问题,所以使用webjars就别用链接表达式):
其它表达式
在基础语法中,默认支持字符串连接、数学运算、布尔逻辑和三目运算等。例如:
代码语言:javascript复制<div th:text="${'I am ' (articles[0].author!=null?articles[0].author:'NoBody')}"></div>
当articles[0].author不为null的时候,显示:dhy,否则显示:NoBody
迭代循环
想要遍历List集合很简单,配合th:each 即可快速完成迭代。但是我们通常有一些需求,在集合的迭代过程还可以获取状态变量。状态变量可用于获取集合的下标/序号、总数、是否为单数/偶数行、是否为第一个/最后一个。例如:
代码语言:javascript复制<table class="table">
<tr>
<td>下标</td>
<td>序号</td>
<td>作者</td>
<td>教程名称</td>
<td>内容</td>
</tr>
<tr th:each="item,stat : ${articles}" th:class="${stat.even}?'even':'odd'">
<td th:text="${stat.index}"></td>
<td th:text="${stat.count}"></td>
<td th:text="${item.author}"></td>
<td th:text="${item.title}"></td>
<td th:text="${item.content}"></td>
</tr>
</table>
迭代下标变量用法:
状态变量定义在一个th:每个属性和包含以下数据:
- index:当前迭代索引,从0开始。这是索引属性。
- count:当前迭代序号,从1开始。这是序号属性。
- size:元素的总量迭代变量。这是大小属性。
- current:变量为每个迭代,当前正迭代的元素
- even/odd:是否当前迭代是奇数还是偶数,布尔属性。
- first:是否第一个当前迭代,布尔属性。
- last:是否最后一个当前迭代,布尔属性。
其中表格隔行换色,即奇数行换色,是通过stat.even实现的。为奇数行单独设置背景颜色
代码语言:javascript复制<style type="text/css">
.odd{
background-color: #7d7d7d;
}
</style>
条件判断
条件判断通常用于动态页面的初始化,例如:
代码语言:javascript复制<div th:if="${articles}">
<div>文章列表存在</div>
</div>
条件判断表达式可以是如下类型:
- boolean 类型并且值是 true, 返回 true
- 数值类型并且值不是 0, 返回 true
- 字符类型(Char)并且值不是 0, 返回 true
- String 类型并且值不是 “false”, “off”, “no”, 返回 true
- 不是 boolean, 数值, 字符, String 的其他类型, 返回 true
- 对象值是 null, 返回 false
如果想取反则使用unless 例如:
代码语言:javascript复制<div th:unless="${articles}">
<div>文章列表暂无.</div>
</div>
thymeleaf内置对象与工具类
内置对象
thymeleaf3.0官网
七大基础对象:
- ${#ctx} 上下文对象,可用于获取其它内置对象。
- ${#param}: 上下文参数变量。
- ${#locale}:上下文区域语言设置对象。
- ${#request}: HttpServletRequest对象。
- ${#response}: HttpServletResponse对象。
- ${#session}: HttpSession对象。
- ${#servletContext}: ServletContext对象。
用法示例
为了演示数据,我们在后端向thymeleaf模板传参的时候,使用不同的对象容器。并注意下图中的参数名称:name1、name2、name3、name4。
上图所示对应的代码:
代码语言:javascript复制@GetMapping("/thymeleaf")
public String index(@RequestParam String name1,
HttpServletRequest request,
Model model) {
List<ArticleVO> articles = articleService.getAll();
request.setAttribute("name2", "curry");
request.getSession().setAttribute("name3", "james");
request.getServletContext().setAttribute("name4","jordan");
model.addAttribute("articles", articles);
//模版名称,实际的目录为:resources/templates/thymeleaftemp.html
return "thymeleaftemp";
}
在thymeleaf模板模板中接收参数
代码语言:javascript复制<h1>ThymeLeaf内置对象</h1>
<br/>语言国家: <span th:text="${#locale.getLanguage() '_' #locale.getCountry()}"></span>
<br/>param: <span th:text="${param.name1}"></span>
<br/>request: <span th:text="${name2}"></span>
<br/>session: <span th:text="${session.name3}"></span>
<br/>application:<span th:text="${application.name4}"></span>
<br/>session包含name3属性么(如不包含显示zoo):<span th:text="${session.name3}?:('zoo')"></span>
<br/>session包含属性数量:<span th:text="${session.size()}"></span>
<br/>session是空的么:<span th:text="${session.isEmpty()}"></span>
访问:http://localhost:8888/template/thymeleaf?name1=dhy, 注意URL中的name1参数
常用的工具类:
内置对象
- #strings:字符串工具类
- #lists:List 工具类
- #arrays:数组工具类
- #sets:Set 工具类
- #maps:常用Map方法。
- #objects:一般对象类,通常用来判断非空
- #bools:常用的布尔方法。
- #execInfo:获取页面模板的处理信息。
- #messages:在变量表达式中获取外部消息的方法,与使用#{…}语法获取的方法相同。
- #uris:转义部分URL / URI的方法。
- #conversions:用于执行已配置的转换服务的方法。
- #dates:时间操作和时间格式化等。
- #calendars:用于更复杂时间的格式化。
- #numbers:格式化数字对象的方法。
- #aggregates:在数组或集合上创建聚合的方法。
- #ids:处理可能重复的id属性的方法。
用法举例:
date工具类之日期格式化
使用默认的日期格式(toString方法) 并不是我们预期的格式:Mon Dec 03 23:16:50 CST 2018
此时可以通过时间工具类#dates来对日期进行格式化:2018-12-03 23:16:50
代码语言:javascript复制<td th:text="${#dates.format(item.createTime,'yyyy-MM-dd HH:mm:ss')}"></td>
首字母大写
代码语言:javascript复制${#strings.capitalizeWords(str)}
list方法
代码语言:javascript复制/*
* 计算list集合中元素数量
*/
${#lists.size(list)}
/*
* 检查集合是否是空的
*/
${#lists.isEmpty(list)}
公共片段(标签)与内联js
片段表达式(标签) ~{}
片段表达式的使用过程,有点像我们平时代码开发过程中的:共用函数抽取,大家按照这个思路,开始我们的学习!
确定哪些代码可重用
下面的head标签片段在很多的页面都存在,并且大部分的内容是一致的,加入我们希望head标签里面的内容能在各个页面内重用,该怎么办?我们本节就带着大家来解决组件代码重用的问题
代码语言:javascript复制<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="'/webjars/bootstrap/4.5.0/css/bootstrap.min.css'">
<style type="text/css">
.odd{
background-color: #7d7d7d;
}
</style>
</head>
定制可重用代码片段
首先通过th:fragment定制代码片段 ,通常将项目里面经常重用的代码抽取为代码片段(标签),代码片段可以设置参数:title、version
代码语言:javascript复制<!-- /templates/common/head.html-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:fragment="static(version,title)">
<meta charset="UTF-8">
<title th:text="${title}"></title>
<link rel="stylesheet"
th:href="'/webjars/bootstrap/' ${version} '/css/bootstrap.min.css'">
<style type="text/css">
.odd{
background-color: #7d7d7d;
}
</style>
</head>
引用可重用代码片段
然后在不同的页面引用该片段,达到代码重用的目的,可以传递参数version、title
代码语言:javascript复制<head th:replace="~{common/head::static('4.5.0','页面标题')}"></head>
最终重用代码组合效果如下:
片段表达式是Thymeleaf的特色之一,细粒度可以达到标签级别,这是JSP无法做到的。 片段表达式拥有三种语法:
- ~{ viewName } 表示引入完整页面
- ~{ viewName ::selector} 表示在指定页面寻找片段其中selector可为片段名、jquery选择器等`,即可以在一个html页面内定义多个片段.
- ~{ ::selector}表示在当前html页查找代码片段
多种片段组合方式
在实际使用中,我们往往使用更简洁的表达,去掉表达式外壳直接填写片段名。例如:
代码语言:javascript复制<div th:replace="common/head::static"></div>
<div th:insert="common/head::static"></div>
<div th:include="common/head::static"></div>
关于thymeleaf th:replace th:include th:insert 的区别
- th:replace :不要自己的主标签,保留th:fragment的主标签。
- th:insert :保留自己的主标签,保留th:fragment的主标签。
- th:include :保留自己的主标签,不要th:fragment的主标签。(官方3.0后不推荐)
值得注意的是,使用替换路径th:replace 开头请勿添加斜杠/,避免部署运行的时候出现路径报错。(因为默认拼接的路径为spring.thymeleaf.prefix = classpath:/templates/)
内联语法
我们之前所讲的内容都是在html标签上使用的thymeleaf的语法,那么如果我们需要在javascript里面获取变量的值(使用之前所讲的表达式),该怎么做?
答:标准格式为:[[${expression}]] ,可以读取服务端变量,也可以调用内置对象的方法。例如获取用户变量和应用路径:
代码语言:javascript复制 <script th:inline="javascript">
var user = [[${articles[0]}]];
var APP_PATH = [[${#request.getContextPath()}]];
var LANG_COUNTRY = [[${#locale.getLanguage() '_' #locale.getCountry()}]];
</script>
HTML页面使用内联语法结果如下:
标签(代码片段)内引入的JS里面能使用内联表达式吗?答:不能!内联表达式仅在页面生效,因为Thymeleaf只负责解析一级视图,不能识别外部标签JS里面的表达式。