【Java从0到架构师】SpringBoot - 页面模版_Thymeleaf

Java 从 0 到架构师目录:【Java从0到架构师】学习记录

Gitee 代码:https://gitee.com/szluyu99/mj_java_frame/tree/master/04_SpringBoot


SpringBoot 中常用的页面模版有:

  • JSP
  • Freemarker
  • Thymeleaf(推荐)

集成 JSP

1、添加 JSP 解析依赖

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
</dependency>

2、配置视图的前缀、后缀、热部署

# application.yml
spring:
  mvc:
    view:
      prefix: /
      suffix: .jsp

# 使得热部署生效
server:
  servlet:
    jsp:
      init-parameters:
        - development: true

3、设置工作目录 (Working directory)

  • 如果是使用 spring-boot-maven-plugin 运行,可以不用设置这一项
    在这里插入图片描述

集成 Thymeleaf

Thymeleaf 是在 SpringBoot 中推荐使用的模版引擎

  • 可以完全取代 JSP
  • 可以在没有服务器的环境下展示静态页面

官网:https://www.thymeleaf.org/


添加依赖:

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

一些默认配置:引入依赖以后就有,不需要自己写

spring:
  thymeleaf:
    encoding: UTF-8
    prefix: classpath:/templates/
    suffix: .html
    enabled: true
    servlet:
      content-type: text/html

在 controller 中可以用 Model 传递数据给模版页面:

Model 参数并非 SpringBoot 独有,可以单独在 SpringMVC 中使用

@Controller
public class TestController {
	@RequestMapping("/test")
	public String test(Model model) {
		model.setAttribute("name", "mj666");
		// classpath:/templates/test.html
		return "test";
	}
}

在页面模版中通过 th:text="${name}" 接收后端传来的值:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
	<div th:text="${name}"></div>
</body>
</html>

Thymeleaf 中属性名都是以 th: 开头:

  • th:text 设置的文本不会进行解析渲染(以文本的形式显示)
  • th:utext 设置的文本会进行解析渲染(以 HTML 的形式显示)

Thymeleaf 中常用表达式:

  • 变量表达式 (Variable):${...}
  • 选中变量表达式 (Selection Variable):*{...}
  • 消息表达式 (Message):#{...}
  • 链接表达式 (Link URL):@{...}
  • 片段表达式 (Fragment):~{...}

关于静态资源的注意点

  • classpath:/templates/ 目录下的内容,默认只能通过转发访问;无法通过 URL 直接访问
  • 通过 spring.resources.static-locations 设置静态资源目录,可以直接通过 URL 访问

Thymeleaf 基本语法

注释 - 3 种

示例代码:thymeleaf 注释

HTML 注释:

<!-- 注释 -->

解释器级别的注释(parser-level)

  • 作为静态页面打开时,可以看见其中内容
  • 只有经过 Thymeleaf 解析器处理后,才会变成真正的注释
<!--/*-->
<div>在解析器处理之前,才能看见这个div</div>
<!--*/-->

原型注释(prototype-only)

  • 作为静态页面打开时,它是注释
  • 经过 Thymeleaf 解释器础处理后,它是正常标签,不是注释
<!--/*/
<div>在解析器处理之后,才能看见这个div</div>
/*/-->

字面量 - ${}

示例代码:thymeleaf 字面量

后端传来的数据为字符串 name=mj,在 th:text 中解析

  • 包含空格,会解析失败:
<!-- 解析失败, 抛出异常 -->
<div th:text="I love coding."></div>
  • 不包含空格会作为字符串解析:
<!-- Ilovecoding -->
<div th:text="Ilovecoding"></div>
  • 使用单引号或 | 可以作为字符串解析:
<!-- I love coding. -->
<div th:text="'I love coding.'"></div>
<div th:text="|I love coding.|"></div>
  • 字符串的拼接:单引号'| 可以互相拼接
<!-- MJ love coding. -->
<div th:text="${name} + 'love coding.'"></div>
<div th:text="${name} + |love| +  'coding.'"></div>
  • | 中可以直接使用 ${},单引号' 中会作为字符串输出
<!-- MJ love coding. -->
<div th:text="|${name} love coding.|"></div>
<!-- ${name} love coding. -->
<div th:text="'${name} love coding.'"></div>

后端传来的数据为数字 age=20,在 th:text 中解析:

<!-- 2020 -->
<div th:test="2020"></div>

<!-- 4040 -->
<div th:test="2020 * 2"></div>

<!-- 0 -->
<div th:test="${age} % 2"></div>
<!-- 布尔值 -->
<!-- true -->
<div th:text="${age} % 2 == 0"></div>
<!-- false -->
<div th:text="${age} <= 10"></div>

[[ ${} ]]

设置文本的另一种方法:使用 [[ ${xx} ]] 可以不用写在标签里

<!-- 下列写法等价 -->
<div>[[ ${name} + '666' ]]</div>
<div th:text="${name} + '666'"></div>

在 js 中要想获取后端传来的数据,或使用 thymeleaf 语法,必须用这种写法:

location.href = '[[@{/comment.html}]]'

局部变量 - th:with、三目运算

示例代码:thymeleaf 字面量

利用 th:with 可以定义局部变量:

<div th:with="isEven=${age % 2 != 0}, myName=${name}">
	<div th:text="${isEven}"></div>
	<div th:text="${myName}" th:class="${isEven} ? 'even' : 'odd'"></div>
</div>

三目运算的使用:

<!-- 下面两种用法等价 -->
<div th:text="${age} == null" ? 'no age' : null></div>
<div th:text="${age} == null" ? 'no age'></div>
<!-- 下列用法等价 -->
<div th:text="${age == null} ? 'no age'"></div>

<div th:text="${age != null} ? ${age} : 'no age'"></div>
<div th:text="${age} ?: 'no age'"></div>

选中变量表达式 - *{}、th:object

示例代码:thymeleaf 选中变量表达式

th:object 的内部只能使用 *{xx} 获取对象的属性的值

  • 或者使用 *{#object.xx}${#object.xx}
  • 其他地方 *{}${} 可以达到一样的效果
<ul th:object="${person}">
	<li th:text="*{id}"></li>
	<li th:text="*{name}"></li>
</ul>

<ul th:object="${person}">
	<li th:text="*{#object.id}"></li>
	<li th:text="${#object.name}"></li>
</ul>

<ul>
	<li th:text="*{person.id}"></li>
	<li th:text="${person.id}"></li>
</ul>

消息表达式 - #{}

示例代码:thymeleaf 消息表达式

消息表达式可以实现国际化 (internationalization,i18n) 的功能

spring:
  messages:
  # 关闭参考系统语言
  fallback-to-system-locale: false
  # 属性文件名(默认就是messages)
  basename: messages

如果将 messages 文件放到了 resources/i18n/ 下,basename 如下:
在这里插入图片描述

新建每个国家地区对应的属性文件

在 thymeleaf 中通过 #{} 取得对应语言文件中的数据

<!-- 切换浏览器的语言设置,就能看到效果 -->
<div th:text="#{login}"></div>

链接表达式 - @{}

示例消息:thymeleaf 链接表达式

当前 URL:http://localhost:8080/test/mj/link
当前 ContextPath:test

  • @{xxx}:相对当前页面
<!-- http://localhost:8080/test/mj/users/login -->
<div><a th:href="@{users/login}">Page-relative</a></div>
  • @{/xxx}:相对项目路径
<!-- http://localhost:8080/test/users/login -->
<div><a th:href="@{/users/login}">Context-relative</a></div>
  • @{~/xxx}:相对服务器
<!-- http://localhost:8080/users/login -->
<div><a th:href="@{~users/login}">Server-relative</a></div>
  • @{//xxx}:相对协议
<!-- http://baidu.com -->
<div><a th:href="@{//baidu.com}">Protocol-relative</a></div>
  • 传参:
<!-- http://localhost:8080/test/users/get?id=10&name=mj&no=18 -->
<div><a th:href="@{/users/get(id=${id}, name=${name}, no=18)}">get</a></div>
<!-- http://localhost:8080/test/users/18/detail -->
<div><a th:href="@{/users/{no}/detail(no=18)}">detail</a></div>

条件判断 - th:if、th:unless、th:switch

<!-- id=20 -->
<!-- 666 -->
<div th:if="${id > 10}">666</div>

<!-- 888 -->
<div th:unless="${id <= 10}">888</div>

通过 th:switch 可以实现 if else 的功能:

<!-- name=MJ -->
<!-- div3 -->
<div th:switch="${name}">
	<div th:case="'test'">div1</div>
	<div th:case="${id}">div1</div>
	<div th:case="*">div3</div>
</div>

遍历 - th:each

示例代码:thymeleaf 遍历

<table>
	<tr>
		<th>row</th>
		<th>id</th>
		<th>name</th>
	</tr>
	<tr th:each="person, status : ${persons}">
		<td th:text="${status.index}"></td>
		<td th:text="${person.id}"></td>
		<td th:text="${person.name}"></td>
	</tr>
</table>

使用 th:object*{} 结合 th:each 来简化代码:

<div th:each="person : ${persons}" th:object="${person}">
	<div th:text="*{id}"></div>
	<div th:text="*{name}"></div>
</div>

block - th:block

th:block 相当于可以取代外层用于循环的标签:

  • 一般使用外层循环效果如下:
    <div>xxxx</div>
    <div>yyyy</div>
    <div>zzzz</div>
    
  • 使用 th:block 不会将外层标签也进行循环:
    <div>
    xxxx
    yyyy
    zzzz
    </div>
    

block 使用示例:

<table>
	<tr>
		<th>row</th>
		<th>id</th>
		<th>name</th>
	</tr>
	<th:block th:each="person, status : ${persons}">
		<td th:text="${status.index}"></td>
		<td th:text="${person.id}"></td>
		<td th:text="${person.name}"></td>
	</th:block>
</table>

利用原型注释,使得 html 不解析 th:block,仅仅作为 thymeleaf 才去解析:

实际上不这么写,也不会有什么影响,了解一下即可

<table>
	<tr>
		<th>row</th>
		<th>id</th>
		<th>name</th>
	</tr>
	<!--/*/ <th:block th:each="person, status : ${persons}"> /*/-->
		<td th:text="${status.index}"></td>
		<td th:text="${person.id}"></td>
		<td th:text="${person.name}"></td>
	<!--/*/ </th:block> /*/-->
</table>

属性设置 - th:attr

示例代码:thymeleaf 属性设置

thymeleaf 中 th:xx 完全等价于 data-th-xx

<!-- 下面写法等价 -->
<div th:text="${name}"></div>
<div data-th-text=${name}></div>

thymeleaf 中可以使用 th:attr 设置属性,多个属性用 , 隔开:

<form th:attr="action=@{/user/get}, method='get'"></form>
<form data-th-attr="action=@{/user/get}, method='get'"></form>
<div class="blue red green"></div>
<div class="red"
	 th:attrprepend="class='blue '"
	 th:attrappend="class=' green'"></div>

内置对象

示例代码:thymeleaf 内置对象

内置对象 - 基础对象:进行数据传递

  • #ctx
  • #vars
  • #locale
  • #request:HttpServletRequest
  • #response:HttpServletResponse
  • #sessionsession:HttpSession
  • #servletContextapplication:ServletContext

内置对象 - 工具对象:封装了对各种类型数据的操作

  • #execInfo#messages#uris#conversions
  • #dates#calendars
  • #numbers#strings#objects#bools
  • #arrays#lists#sets#maps
  • #aggregates#ids

视图映射 - WebMvcConfigurer

示例代码:thymeleaf 视图映射

默认情况下,SpringBoot 会把 index 视图当做是首页 (classpath:/templates/index.html)

可以通过 WebMvcConfigurer 进行视图映射,简化 controller 代码

  • 不需要仅仅为了跳转页面,就在 controller 中写一个方法
@Configuration
public class SpringMVCConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // 首页的映射
        registry.addViewController("/").setViewName("login");

        // 其他页面的映射
        registry.addViewController("/i18n").setViewName("i18n");
		registry.addViewController("/i18n/").setViewName("i18n");
    }
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

萌宅鹿同学

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

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

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

打赏作者

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

抵扣说明:

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

余额充值