前言

在一个Web应用中,通常会采用MVC设计模式实现对应的模型、视图和控制器,其中,视图是用户看到并与之交互的界面。对最初的Web应用来说,视图是由HTML元素组成的静态界面;而后期的Web应用更倾向于使用动态模板技术,从而实现前后端分离和页面的动态数据展示。Spring Boot框架为简化项目的整体开发,提供了一些视图技术支持,并主要推荐整合模板引擎技术实现前端页面的动态化内容。本文对SpringBoot常用的Thymeleaf进行整合。

Thymeleaf基本语法

Thymeleaf是一种现代的基于服务器端的Java模板引擎技术,也是一个优秀的面向Java的XML、XHTML、HTML5页面模板,它具有丰富的标签语言、函数和表达式,在使用Spring Boot框架进行页面设计时,一般会选择 Thymeleaf模板。我们在这里学习Thymeleaf 常用的标签、表达式。

常用标签

标签

Thymeleaf标签

th:标签 说明
th:insert 页面片段包含(类似JSP中的include标签)
th:replace 页面片段包含(类似JSP中的include标签)
th:each 元素遍历(类似JSP中的c:forEach标签)
th:if 条件判断,条件成立时显示th标签内容
th:unless 条件判断,条件不成立时显示内容
th:switch 条件判断,进行选择性匹配
th:case th:switch分支,选择的元素
th:object 用于替换对象
th:with 用于定义局部遍历
th:attr 用于属性修改
th:attrprepend 通用属性修改,将计算结果追加前缀到现有属性值
th:attrappend 通用属性修改,将计算的结果追加后缀现有属性值
th:value 属性值修改,指定标签属性值
th:href 用于设定链接地址
th:src 用于设定链接地址
th:text 用于指定标签显示文本内容
th:utext 用于指定标签显示内容,对特殊标签不转译
th:fragment 声明片段
th:removve 移除片段

如何使用标签

使用标签只需要加上一个命名空间就可以了。<html lang="en" xmlns:th="http://thymeleaf.org"> 即修改原html的第二行就可以了。

<!DOCTYPE html>

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

  <head>
<title>Good Thymes Virtual Grocery</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" media="all"
href="../../css/gtvg.css" th:href="@{/css/gtvg.css}" />
</head> <body> <p th:text="#{home.welcome}">Welcome to our grocery store!</p> </body> </html>

标准表达式

表达式 说明
${..} 变量表达式
*{..} 选择变量表达式
#{..} 消息表达式
@{..} 链接URL表达式
~{..} 片段表达式

变量表达式

变量表达式${..}主要用于获取上下文中的变量值,示例代码如下。

这是标题

- 使用了Thymeleaf模板的变量表达式${..}用来动态获取p标签中的内容
- 如果当前程序没有启动或者当前上下文中不存在title变量,该片段会显示标签默认值“这是标题”;
- 如果当前上下文中存在title 变量并且程序已经启动,当前p标签中的默认文本内容将会被tite变量的值所替换,从而达到模板引擎页面数据动态替换的效果。


Thymeleaf为变量所在域提供了一些内置对象

内置对象 说明
#ctx 上下文对象
#vars 上下文变量
#locale 上下文区域设置
#request (仅限 Web Context)HttpServletRequest 对象
#response (仅限Web Context)HttpServletResponse 对象
#session 仅限Web Context) HttpSession对象
#servletContext (仅限 Web Context)ServletContext 对象

结合上述内置对象的说明,假设要在Thymeleaf模板擎页面中动态获取当前国家信息,可以使用#locale内置对象

<span th:text="${#locale.country}">China</span>

选择变量表达式

选择交量表达式和变量表达式用法类似,一般用于从被选定对象而不是上下文中获取属性值,如果没有选定对象,则和变量表达式一样,示例代码如下。

<div th:object="$(session.user)">
<p>Name: <span th:text="s(object.firstName)">Sebastiahk</span></p>
<p>username:<span th:text="$(session.user,lastName)">Pepper</span></p>
<p>Nationality:<span th:text="*(nationality)">Saturn</span>.</p>
</div>
  • ${#object.firstName}变量表达式使用Thymeleaf模板提供的内置对象object获取当前上下文对象中的frstName属性值;
  • ¥{session.user.lastName}变量表达式获取当前user对象的lastName属性值;
  • *{nationality}选择变量表达式获取当前指定对象user的nationality属性值。

消息表达式

消息表达式#{..}主要用于Thymeleaf模板页面国际化内容的动态替换和展示。使用消息表这式#{..}进行国际化设置时,还需要提供一些国际化配置文件。关于消息表达式的使用,下文写国际化时会详细说明。

链接表达式

链接表达式@{..}一般用于页面跳转或者资源的引入,在Web开发中占据着非常重要的地位,并且使用也非常频繁。

<a href="details.html" th:href="@{http:localhost:8080/gtvg/order/details(order=$o.id})}">view</a>
<a href="details.html" th:href="@{/order/details(order=$o.id})}">view</a>
  • @{..}分别编写了绝对链接地址和相对链接地址。
  • 在有参表达式中,需要按照@(路径(参数名称=参数值.参数名称=参数值..))的形式编写,同时该参数的值可以使用变量表达式来传递动态参数值。

片段表达式

片段表达式~{..}是一种用来将标记片段移动到模板中的方法。其中,最常见的用法是使用th:insert或th:replace 属性插入片段

<div th:insert="~(thymeleafDemo::title】"></div>
  • th:insert属性将title片段模板引用到该
    标签中。
  • thymelcafDemo为模板名称,Thymeleal会自动查找“classpathy/resources/templates/”目录下的thymeleaDemo模板,title为声明的片段名称。

Thyemleaf基本使用

静态资源访问

Spring Boot默认设置了静态资源的访问路径,默认将/**所有访问映射到以下目录。

  • classpath:/META-INF/resources/:项目类路径下的META-INF文件夹下的resources文件夹下的所有文件。
  • classpath:/resources/:项目类路径下的resources文件夹下的所有文件。
  • classpath:/static/:项目类路径下的static文件夹下的所有文件。
  • classpath:/public/:项目类路径下的public文件夹下的所有文件。
  • Spring Initializr 方式创建的 Spring Boot 项目会默认生成一个 resources目录,在resources目录中新建public、resources、static3个子目录,Spring Boot默认会依次从public、resources、static里面查找静态资源。

Thymeleaf页面展示

我们创建一个springboot项目用于本次实验。项目名为springboot_01_thyme。java8,springboot2.6.6

导入Thymeleaf依赖

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

编写配置文件


# thymeleaf cache
spring.thymeleaf.cache=false spring.thymeleaf.encoding=utf-8
spring.thymeleaf.mode=HTML5
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

创建WEB控制类

创建一个LoginController类用于数据替换效果测试。

package com.hjk.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; import java.util.Calendar; @Controller
public class LoginController {
@GetMapping("toLoginPage")
public String toLoginPage(Model model){
model.addAttribute("currentYear", Calendar.getInstance().get(Calendar.YEAR));
return "login";
} }

创建模板页面并引入静态资源

我们写一个login.html进行测试。我们导入一个bootstrap的样式到static/login里面,并且自己定义一些css。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1,shrink-to-fit=no">
<title>用户登录界面</title>
<link th:href="@{/login/css/bootstrap.min.css}" rel="stylesheet">
<style type="text/css">
html,
body {
height: 100%;
}
body {
align-items: center;
padding-top: 40px;
padding-bottom: 40px;
background-color: greenyellow;
}
.form-signin {
width: 100%;
max-width: 330px;
padding: 15px;
margin: 0 auto;
}
</style> </head>
<body class="text-center">
<!-- 用户登录form表单 -->
<form class="form-signin">
<h1 class="h3 mb-3 font-weight-normal">请登录</h1>
<input type="text" placeholder="用户名">
<input type="password" placeholder="密码">
<div>
<label>
<input type="checkbox" value="remember-me"> 记住我
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">登录</button>
<p class="mt-5 mb-3 text-muted"> <span th:text="${currentYear}">2018</span>-<span th:text="${currentYear}+1">2019</span></p>
</form>
</body>
</html>
  • 我们使用xmlns:th="http://thymeleaf.org"引入Thymeleaf标签
  • 通过th:href引入外联css
  • 通过th:text后台动态传递年份currentYear

最后我们通过访问http://localhost:8080/toLoginPage 可以查看效果

配置国际化页面

编写多语言配置文件

在resources目录下创建名为i18n的文件夹,数一数这个单词多少个字母internationalization,就知道为什么叫i18n了。

然后我们在i18n文件夹下面创建login.properties、 login_zh_CN.properties、 login_en_US.properties文件。

目录结构:这个Resource Bundle 'login'时idea自动创建的,我们不需要管,只需要完成我们的就行。

login.properties

login.tip=请登录
login.username=用户名
login.password=密码
login.rememberme=记住我
login.button=登录

login_zh_CN.properties

login.tip=请登录
login.username=用户名
login.password=密码
login.rememberme=记住我
login.button=登录

login_en_US.properties

login.tip=Please sign in
login.username=Username
login.password=Password
login.rememberme=Rememberme
login.button=Login

然后我们在配置文件application.properties里面添加代码

  • 这个是我们必须要写的,login是我们的语言文件前缀,springboot默认前缀是messages,所以不写识别不了。

    spring.messages.basename=i18n.login

定制区域信息解析器

我们在config包下面创建一个MyLocalResovel类,自定义国际化功能区域信息解析器。

package com.hjk.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale; @Configuration
public class MyLocalResovel implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
String parameter = request.getParameter("1");
String header = request.getHeader("Accept-Language");
Locale locale = null;
if (!StringUtils.isEmpty(parameter)){
String[] s = parameter.split("_");
locale = new Locale(s[0], s[1]);
}else{
String[] split = header.split(",");
String[] split1 = split[0].split("-");
locale = new Locale(split1[0],split1[1]);
}
return locale;
} @Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) { } @Bean
public LocaleResolver localeResolver(){
return new MyLocalResovel();
} }
  • 注意分割符的两个下滑线,不一样

重写login.html实现国际化

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1,shrink-to-fit=no">
<title>用户登录界面</title>
<link th:href="@{/login/css/bootstrap.min.css}" rel="stylesheet">
<style type="text/css">
html,
body {
height: 100%;
}
body {
align-items: center;
padding-top: 40px;
padding-bottom: 40px;
background-color: greenyellow;
}
.form-signin {
width: 100%;
max-width: 330px;
padding: 15px;
margin: 0 auto;
}
</style> </head>
<body class="text-center">
<!-- 用户登录form表单 -->
<form class="form-signin">
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">请登录</h1>
<input type="text" th:placeholder="#{login.username}">
<input type="password" th:placeholder="#{login.password}" \>
<div>
<label>
<input type="checkbox" value="remember-me"> [[#{login.rememberme}]]
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.button}">登录</button>
<p class="mt-5 mb-3 text-muted"> <span th:text="${currentYear}">2018</span>-<span th:text="${currentYear}+1">2019</span></p>
<a class="btn btn-sm" th:href="@{/toLoginPage(1='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/toLoginPage(1='en_US')}">English</a>
</form>
</body>
</html>

这里我们基本就完成了,但是在访问中文的时候会出现乱码现象。

我们打开idea的file->settings->file Encodings.

将Default encoding for properties的编码改为utf-8,同时勾选Transparentnative-to-ascii conversion

然后我们重新编写login.properties和其他相关的

login.tip=请登录
login.username=用户名
login.password=密码
login.rememberme=记住我
login.button=登录

但是这种方法1只对当前项目有效。下次创建还是使用GBK编码

总结

本文我们主要了解了Thymeleaf的基本语法、标签、表达式、基本使用、同时还实现了页面登录页得国际化。

....

【SpringBoot实战】视图技术-Thymeleaf的更多相关文章

  1. SpringBoot实战(五)之Thymeleaf

    Thymeleaf同jsp.volocity.freemarker等共同的职能是MVC模式中的视图展示层,即View. 当然了,SpringBoot中也可以用jsp,不过不推荐这种用法,比较推崇的就是 ...

  2. 千锋很火的SpringBoot实战开发教程视频

    springboot是什么? Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员 ...

  3. SpringBoot: 9.整合thymeleaf(转)

    1.创建maven项目,添加项目所需依赖 <!--springboot项目依赖的父项目--> <parent> <groupId>org.springframewo ...

  4. SpringBoot 之 视图解析与模板引擎、 热部署、日志配置(四)

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一 . SpringBoot环境下的视图解析技术 1. JSP JSP 是我们常用的视图技术了,但是Sp ...

  5. springboot实战开发全套教程,让开发像搭积木一样简单!Github星标已上10W+!

    前言 先说一下,这份教程在github上面星标已上10W,下面我会一一给大家举例出来全部内容,原链接后面我会发出来!首先我讲一下接下来我们会讲到的知识和技术,对比讲解了多种同类技术的使用手日区别,大家 ...

  6. SpringBoot实战 之 异常处理篇

    在互联网时代,我们所开发的应用大多是直面用户的,程序中的任何一点小疏忽都可能导致用户的流失,而程序出现异常往往又是不可避免的,那该如何减少程序异常对用户体验的影响呢?其实方法很简单,对异常进行捕获,然 ...

  7. SpringBoot整合Jsp和Thymeleaf (附工程)

    前言 本篇文章主要讲述SpringBoot整合Jsp以及SpringBoot整合Thymeleaf,实现一个简单的用户增删改查示例工程.事先说明,有三个项目,两个是单独整合的,一个是将它们整合在一起的 ...

  8. apollo客户端springboot实战(四)

    1. apollo客户端springboot实战(四) 1.1. 前言   经过前几张入门学习,基本已经完成了apollo环境的搭建和简单客户端例子,但我们现在流行的通常是springboot的客户端 ...

  9. java框架之SpringBoot(4)-资源映射&thymeleaf

    资源映射 静态资源映射 查看 SpringMVC 的自动配置类,里面有一个配置静态资源映射的方法: @Override public void addResourceHandlers(Resource ...

随机推荐

  1. 数据库篇:mysql锁详解

    前言 sql事务的执行,如果需要锁定数据进行更新操作,则必定离不开锁 共享锁和排他锁 表锁 行锁 Record Lock 间隙锁 Gap Lock 行锁+间隙锁 Next-Key Lock 加锁场景( ...

  2. springMVC和struts2的区别有哪些?

    (1)springmvc的入口是一个servlet即前端控制器(DispatchServlet),而struts2入口是一个filter过虑器(StrutsPrepareAndExecuteFilte ...

  3. 简述 synchronized 和 java.util.concurrent.locks.Lock 的异同?

    Lock 是 Java 5 以后引入的新的 API,和关键字 synchronized 相比主要相同点: Lock 能完成 synchronized 所实现的所有功能:主要不同点:Lock 有比 sy ...

  4. Java 中 Semaphore 是什么?

    Java 中的 Semaphore 是一种新的同步类,它是一个计数信号.从概念上讲,从 概念上讲,信号量维护了一个许可集合.如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可.每 ...

  5. 在虚拟机里面运行java程序

    首先输入vi在里面写一个java程序 然后再查找jdk 复制jdk名字 然后安装jdk 安装完之后输入Javac加你创建的文件名 然后再输入Java 和文件名(这个不要加后缀)然后就打印出来了

  6. 描述 Java 中的重载和重写?

    重载和重写都允许你用相同的名称来实现不同的功能,但是重载是编译时活动, 而重写是运行时活动.你可以在同一个类中重载方法,但是只能在子类中重写方 法.重写必须要有继承.

  7. Effective Java —— 避免创建不必要的对象

    本文参考 本篇文章参考自<Effective Java>第三版第六条"Avoid creating unnecessary objects" avoid creatin ...

  8. pandas学习总结

    什么是pandas pandas数据读取 03. Pandas数据结构 Pandas查询数据的几种方法

  9. Top 15 - Material Design框架和类库(译)

    _Material design_是Google开发的,目的是为了统一公司的web端和手机端的产品风格.它是基于很多的原则,比如像合适的动画,响应式,以及颜色和阴影的使用.完整的指南详情请看这里(ht ...

  10. A Beginner’s Introduction to CSS Animation中文版

    现在越来越多的网站正在使用动画,无论是以GIF,SVG,WebGL,背景视频等形式. 当正确使用时,网络上的动画带来生机和交互性,为用户增添了额外的反馈和体验. 在本教程中,我将向您介绍CSS动画; ...