【SpringBoot详细教程】-07-整合Thymeleaf模板引擎与静态资源【持续更新】

======关注点一点,友谊深一点=====

🌲 静态资源访问

在我们开发web应用的时候,需要引入大量的js、css、图片等静态资源。

默认配置

SpringBoot 默认提供的静态资源目录位置需要置于classpath下,目录名需要符合如下规则:

  • /static
  • /public
  • /resources
  • /META-INF/resources

举例:我们可以在 src/main/resources/ ⽬录下创建 static ,在该位置放置⼀个图⽚⽂件。启动

程序后,尝试访问 http://localhost:8080/D.jpg 。如能显示图⽚,配置成功。

提示:有的时候复制图片到idea之后,无法更新图片到项目中,这个时候访问不到图片,此时可以rebuild project 重构一下项目,再启动服务即可看到图片。

渲染Web⻚⾯

在之前的示例中,我们都是通过@RestController来处理请求,所以返回的内容为json对象。那么如果需要渲染html⻚⾯的时候,要如何实现呢?

🌲 模板引擎

SpringBoot实际上不推荐使用JSP,而使用HTML去实现动态页面。在动态HTML实现上Spring Boot依然可以完美胜任,并且提供了多种模板引擎的默认配置⽀持,所以在推荐的模板引擎下,我们可以很快的上⼿开发动态⽹站。

SpringBoot提供了默认配置的模板引擎主要有以下⼏种:

  • Thymeleaf
  • FreeMarker
  • Velocity
  • Groovy
  • Mustache

SpringBoot建议使⽤这些模板引擎,避免使⽤JSP,若⼀定要使⽤JSP将⽆法实现SpringBoot的多 种特性,

当你使⽤上述模板引擎中的任何⼀个,它们默认的模板配置路径为:src/main/resources/templates 。当然也可以修改这个路径,具体如何修改,可在后续各模板引擎的配置属性中查询并修改。

🌲 Thymeleaf模板引擎

🌾 Thymeleaf 简介

Thymeleaf是⼀个XML/XHTML/HTML5模板引擎,可⽤于Web与⾮Web环境中的应⽤开发。它是⼀个开源的Java库,基于Apache License 2.0许可,由Daniel Fernández创建,该作者还是Java加密库Jasypt的作者。

Thymeleaf提供了⼀个⽤于整合SpringMVC的可选模块,在应⽤开发中,你可以使⽤Thymeleaf来完全代替JSP或其他模板引擎,如Velocity、FreeMarker等。Thymeleaf的主要⽬标在于提供⼀种可被浏览 器正确显示的、格式良好的模板创建⽅式,因此也可以⽤作静态建模。你可以使⽤它创建经过验证的 XML与HTML模板。相对于编写逻辑或代码,开发者只需将标签属性添加到模板中即可。接下来,这些标签属性就会在DOM(⽂档对象模型)上执⾏预先制定好的逻辑。

示例模板:

<table>
  <thead>
    <tr>
      <th th:text="#{msgs.headers.name}">Name</td>
    <th th:text="#{msgs.headers.price}">Price</td>
  </tr>
  </thead>
  <tbody>
    <tr th:each="prod	:	${allProducts}">
      <td th:text="${prod.name}">Oranges</td>
      <td th:text="${#numbers.formatDecimal(prod.price,1,2)}">0.99</td>
    </tr>
  </tbody>
</table>

可以看到Thymeleaf主要以属性的⽅式加⼊到html标签中,浏览器在解析html时,当检查到没有的属性时候会忽略,所以Thymeleaf的模板可以通过浏览器直接打开展现,这样⾮常有利于前后端的分离。

在SpringBoot中使⽤Thymeleaf,只需要引⼊下⾯依赖,并在默认的模板路径src/main/resources/templates 下编写模板⽂件即可完成。

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

在完成配置之后,举⼀个简单的例⼦,在快速⼊⻔⼯程的基础上,举⼀个简单的示例来通过Thymeleaf 渲染⼀个⻚⾯。

  • 首先在resources/templates目录中新建一个index.html,代码如下:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
	<h2 th:text="${msg}"></h2>
</body>
</html>

注意:在使用Thymeleaf需要先声明语法规则,具体代码如下:

<html lang="en" xmlns:th="http://www.thymeleaf.org">
  • 然后添加Controller控制器方法,代码如下:
package com.moxuan.boot_07_thymeleaf.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class ThymeleafController {

    @RequestMapping("/show")
    public String showMsg(Model model){
        model.addAttribute("msg","攀哥帅呀");
        return "index";
    }
}
  • 打开浏览器,发送请求进行测试:

🌾 Thymeleaf的默认参数配置

如有需要修改默认配置的时候,只需复制下⾯要修改的属性到 application.properties 中,并修改

成需要的值,如修改模板⽂件的扩展名,修改默认的模板路径等。

#	Enable	template	caching.
spring.thymeleaf.cache=true
#	Check	that	the	templates	location	exists.
spring.thymeleaf.check-template-location=true
#	Content-Type	value.
spring.thymeleaf.content-type=text/html	
#	Enable	MVC	Thymeleaf	view	resolution.
spring.thymeleaf.enabled=true
#	Template	encoding.
spring.thymeleaf.encoding=UTF-8	
#	Comma-separated	list	of	view	names	that	should	be	excluded	from	resolution.
spring.thymeleaf.excluded-view-names=	
#	Template	mode	to	be	applied	to	templates.	See	also	StandardTemplateModeHandlers.
spring.thymeleaf.mode=HTML5	
#	Prefix	that	gets	prepended	to	view	names	when	building	a	URL.
spring.thymeleaf.prefix=classpath:/templates/	
#	Suffix	that	gets	appended	to	view	names	when	building	a	URL.
spring.thymeleaf.suffix=.html		

🌾 Thymeleaf 的特点

Thymeleaf 模板引擎具有以下特点:

  • 动静结合:Thymeleaf 既可以直接使用浏览器打开,查看页面的静态效果,也可以通过 Web 应用程序进行访问,查看动态页面效果。
  • 开箱即用:Thymeleaf 提供了 Spring 标准方言以及一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。
  • 多方言支持:它提供了 Thymeleaf 标准和 Spring 标准两种方言,可以直接套用模板实现 JSTL、 OGNL 表达式;必要时,开发人员也可以扩展和创建自定义的方言。
  • 与 SpringBoot 完美整合:SpringBoot 为 Thymeleaf 提供了的默认配置,并且还为 Thymeleaf 设置了视图解析器,因此 Thymeleaf 可以与 Spring Boot 完美整合。

🌾 Thymeleaf 语法规则

在使用 Thymeleaf 之前,首先要在页面的 html 标签中声明名称空间,示例代码如下。

<html lang="en" xmlns:th="http://www.thymeleaf.org">

在 html 标签中声明此名称空间,可避免编辑器出现 html 验证错误,但这一步并非必须进行的,即使我们不声明该命名空间,也不影响 Thymeleaf 的使用。

Thymeleaf 模板引擎支持多种表达式:

表达式名字

语法

用途

变量取值

${...}

获取请求域、session域、application域,对象等值

选择变量

*{...}

获取上下文对象值,简化自定义对象属性的访问

消息

#{...}

获取国际化等值(根据地区语言环境,获取各个国家地区语言文字)

链接

@{...}

生成链接(对静态页面连接赋予动态项目名支持)

片段表达式

~{...}

jsp:include 作用,引入公共页面片段

🍁 变量

Thymeleaf通过${}来获取model中的变量,注意这不是el表达式,而是ognl表达式,但是语法非常像。

  • 新建User类,代码如下:
package com.moxuan.boot_07_thymeleaf.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    String name;
    int age;
    User friend;// 对象类型属性

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
  • 控制器中将User数据封装到model中:
@RequestMapping("/show2")
public String show2(Model model){
    User user = new User();
    user.setAge(21);
    user.setName("Jack Chen");
    user.setFriend(new User("李小龙", 30));
    
    model.addAttribute("user", user);
    return "index";
}
  • 在index.html中获取数据
<h2>
  <p>Name: <span th:text="${user.name}"></span>.</p>
  <p>Age: <span th:text="${user.age}"></span>.</p>
  <p>friend: <span th:text="${user.friend.name}"></span>.</p>
</h2>
  • 运行效果

当实体类属性数量比较多的时候,频繁的写user.就会非常麻烦。因此,Thymeleaf提供了自定义变量来解决,修改上面index.html代码如下:

<h2 th:object="${user}">
    <p>Name: <span th:text="*{name}">Jack</span>.</p>
    <p>Age: <span th:text="*{age}">21</span>.</p>
    <p>friend: <span th:text="*{friend.name}">Rose</span>.</p>
</h2>
  • 首先在 h2上 用 th:object="${user}"获取user的值,并且保存
  • 然后,在h2内部的任意元素上,可以通过 *{属性名}的方式,来获取user中的属性,这样就省去了大量的user.前缀了

🍁 方法

Thymeleaf支持方法调用,例如:

<h2 th:object="${user}">
    <p>FirstName: <span th:text="*{name.split(' ')[0]}">Jack</span>.</p>
    <p>LastName: <span th:text="*{name.split(' ')[1]}">Li</span>.</p>
</h2>

这里我们调用了name(是一个字符串)的split方法。

🍁 字面值

有的时候,我们需要在指令中填写基本类型如:字符串、数值、布尔等,并不希望被Thymeleaf解析为变量,这个时候称为字面值。

早期版本需要使用一对'单引号引用的内容就是字符串字面值了:

<p>
    你正在观看 <span th:text="'攀帅讲解的'">Thymeleaf</span> 的字符串常量值.
</p>

目前的版本可以直接写

<p>
    你正在观看 <span th:text="憨批讲解的">Thymeleaf</span> 的字符串常量值.
</p>

数字字面量

<p>今年是 <span th:text="2023">1900</span>.</p>
<p>两年后将会是 <span th:text="2023+ 2">1902</span>.</p>

布尔字面量

<div th:if="true">
    你是"处"
</div>

🍁 字符串拼接

我们经常会用到普通字符串与表达式拼接的情况:

<span th:text="'欢迎您:' + ${user.name} + '!'"></span>

字符串字面值拼接需要用'',拼接起来非常麻烦,Thymeleaf对此进行了简化,使用一对|即可:

<span th:text="|欢迎您:${user.name}|"></span>

与上面是完全等效的,这样就省去了字符串字面值的书写。

🌾 运算符

需要注意:${}内部的是通过OGNL表达式引擎解析的,外部的才是通过Thymeleaf的引擎解析,因此运算符尽量放在${}外进行。

🍁算术运算符

支持的算术运算符:+ - * / %

<span th:text="${user.age}"></span>
<span th:text="${user.age}%2 == 0"></span>
🍁 条件运算符

三元运算

<span th:text="${user.sex} ? '男':'女'"></span>

三元运算符的三个部分:conditon ? then : else

  • condition:条件
  • then:条件成立的结果
  • else:不成立的结果

其中的每一个部分都可以是Thymeleaf中的任意表达式。

有的时候,我们取一个值可能为空,这个时候需要做非空判断,可以使用 表达式 ?: 默认值简写:

<span th:text="${user.name} ?: '二狗'"></span>

🌾Thymeleaf 内置对象

Thymeleaf中提供了一些内置对象,并且在这些对象中提供了一些方法,方便我们来调用。获取这些对象,需要使用#对象名来引用。

🍁 环境相关对象

对象

作用

#ctx

获取Thymeleaf自己的Context对象

#request

如果是web程序,可以获取HttpServletRequest对象

#response

如果是web程序,可以获取HttpServletReponse对象

#session

如果是web程序,可以获取HttpSession对象

#servletContext

如果是web程序,可以获取HttpServletContext对象

🍁全局对象

对象

作用

#dates

处理java.util.date的工具对象

#calendars

处理java.util.calendar的工具对象

#numbers

用来对数字格式化的方法

#strings

用来处理字符串的方法

#bools

用来判断布尔值的方法

#arrays

用来护理数组的方法

#lists

用来处理List集合的方法

#sets

用来处理set集合的方法

#maps

用来处理map集合的方法

我们在Controller中添加日期类型对象

@RequestMapping("/show3")
public String show3(Model model){
    model.addAttribute("today", new Date());
    return "date";
}

新建date.html,代码如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<p>
    今天是: <span th:text="${#dates.format(today,'yyyy-MM-dd')}">2018-04-25</span>
</p>

</body>
</html>

🌾 循环遍历

循环也是非常频繁使用的需求,我们可以使用th:each指令来完成

🍁 遍历list集合
  • 在控制器中准备数据
@RequestMapping("/show4")
public String show4(Model model){
    List<User> users = new ArrayList<User>();
    users.add(new User("周润发",65));
    users.add(new User("梁朝伟",63));
    users.add(new User("刘德华",61));
    System.out.println(users);
    model.addAttribute("users",users);
    return "foreach";
}
  • 添加foreach.html ,代码如下:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h2>
    用户列表
</h2>
<table border="1" width="50%" cellspacing="0" cellpadding="0" height="500px">
    <tr>
        <td>姓名</td>
        <td>年龄</td>
    </tr>
        <tr th:each="user:${users}">
            <td th:text="${user.name}">攀哥</td>
            <td th:text="${user.age}">18</td>
        </tr>
</table>
</body>
</html>
  • 在迭代的同时,我们也可以获取迭代的状态对象:
<h2>
    用户列表
</h2>
<table border="1" width="50%" cellspacing="0" cellpadding="0" height="500px">
    <tr>
        <td>姓名</td>
        <td>年龄</td>
        <td>序号</td>
    </tr>
    <tr th:each="user,stat:${users}">
        <td th:text="${stat.count}"></td>
        <td th:text="${user.name}">攀哥</td>
        <td th:text="${user.age}">18</td>
    </tr>
</table>

stat对象包含以下属性:

  • index,从0开始的角标
  • count,元素的个数,从1开始
  • size,总元素个数
  • current,当前遍历到的元素
  • even/odd,返回是否为奇偶,boolean值
  • first/last,返回是否为第一或最后,boolean值

🍁 遍历map集合
  • 在控制器中准备数据:
@RequestMapping("/show4")
public String show4(Model model){
    List<User> users = new ArrayList<User>();
    users.add(new User("周润发",65));
    users.add(new User("梁朝伟",63));
    users.add(new User("刘德华",61));
    System.out.println(users);
    model.addAttribute("users",users);
    
    Map<String,User> maps = new HashMap<>();
    maps.put("fg",new User("周润发",65));
    maps.put("wg",new User("梁朝伟",63));
    maps.put("hg",new User("刘德华",61));
    
    model.addAttribute("maps",maps);
    return "foreach";
}
  • 在foreach.html中添加遍历map集合的代码
<p th:each="userMap,stat:${maps}">
    <span th:text="${stat.count}"></span>
  <!--getKey() 获取键  -->
    <span th:text="${userMap.getKey()}"></span>
    <span th:text="${userMap.value.name}"></span>
    <span th:text="${userMap.value.age}"></span>
</p>

🌾 逻辑判断

🍁 if判断

Thymeleaf中使用th:if 或者 th:unless ,两者的意思恰好相反。

  • 修改控制器中的数据
List<User> users = new ArrayList<User>();
users.add(new User("周润发",65));
users.add(new User("梁朝伟",63));
users.add(new User("彭于晏",48));
System.out.println(users);
model.addAttribute("users",users);
  • 修改foreach.html中的表格代码添加”状态“列
<h2>
    用户列表
</h2>
<table border="1" width="50%" cellspacing="0" cellpadding="0" height="500px">
    <tr>
        <td>姓名</td>
        <td>年龄</td>
        <td>序号</td>
        <td>状态</td>
    </tr>
    <tr th:each="user,stat:${users}">
        <td th:text="${stat.count}"></td>
        <td th:text="${user.name}">攀哥</td>
        <td th:text="${user.age}">18</td>
        <td th:if="${user.age} > 60"> 老baby</td>
        <td th:unless="${user.age} > 60"> 魅力王</td>
    </tr>
</table>

🍁 分支switch

这里要使用两个指令:th:switchth:case

需要注意的是,一旦有一个th:case成立,其它的则不再判断。与java中的switch是一样的。

另外th:case="*"表示默认,放最后。


<h2>
    用户列表
</h2>
<table border="1" width="50%" cellspacing="0" cellpadding="0" height="500px">
    <tr>
        <td>姓名</td>
        <td>年龄</td>
        <td>序号</td>
        <td>状态</td>
        <td>角色</td>
    </tr>
    <tr th:each="user,stat:${users}" >
        <td th:text="${stat.count}"></td>
        <td th:text="${user.name}">攀哥</td>
        <td th:text="${user.age}">18</td>
        <td th:if="${user.age} > 60"> 老baby</td>
        <td th:unless="${user.age} > 60"> 魅力王</td>
        <td th:switch="${user.role}">
            <p th:case="admin" style="background:red" th:text="超级管理员"></p>
            <p th:case="user" style="background:green" th:text="普通用户"></p>
            <p th:case="manager" style="background:blue" th:text="部门经理"></p>
            <p th:case="*" style="background:yellow" th:text="啥也不是"></p>
        </td>

    </tr>
</table>

修改控制器层数据源:

List<User> users = new ArrayList<User>();
users.add(new User("周润发",65,"admin"));
users.add(new User("梁朝伟",63,"manager"));
users.add(new User("彭于晏",48,"user"));
users.add(new User("宋喆",20));
System.out.println(users);
model.addAttribute("users",users);

更多学习资料:小破(B)站: 墨轩大楼 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

听潮阁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值