Thymeleaf 是一个现代服务器端 Java 模板引擎,适用于 Web 和独立环境。
【官网地址】:https://www.thymeleaf.org/
Thymeleaf是一款现代化的Java模板引擎,适用于Web和独立开发。
对前后端的协同工作非常友好相比于之前的传统的试图模板那引擎JSP而言。
可以处理HTML,CSS,JavaScript甚至纯文本。
要使用Thymeleaf的提示功能,可以在HTML的标签里添加如下命名空间
<html lang="en" xmlns:th="http://www.thymeleaf.org">
目前最新的Thymeleaf版本已经是3.0,在之前的老版本可能要使用如下的声明
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
声明:
以上的方式针对于Idea用户,可以很好的提示,但是针对Eclipse用户需要安装Thymeleaf插件
如果需要 下载,可以去Spring的官网下载,或者自行百度搜索。
这里以SpringBoot来演示,下面为SpringBoot与 Thymeleaf的整合步骤
Thymleaf的SpringBoot启动支持依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
当我们加上这个依赖就代表SpringBoot已经帮我们将Thymeleaf自动配置了
【源码】ThymeleafAutoConfiguration类
@EnableConfigurationProperties({ThymeleafProperties.class})
@ConditionalOnClass({TemplateMode.class, SpringTemplateEngine.class})
@AutoConfigureAfter({WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class})
public class ThymeleafAutoConfiguration {
}
自动配好的策略:
ThymeleafProperties类
如果说想要自己定义Thymeleaf的一些配置,也可以在yml或者properties里自己定义:下面给出一个properties的样例:
# 应用名称
spring.application.name=boot-05-web-admin
# 应用服务 WEB 访问端口
server.port=8080
# THYMELEAF (ThymeleafAutoConfiguration)
# 开启模板缓存(默认值: true )
spring.thymeleaf.cache=true
# 检查模板是否存在,然后再呈现
spring.thymeleaf.check-template=true
# 检查模板位置是否正确(默认值 :true )
spring.thymeleaf.check-template-location=true
#Content-Type 的值(默认值: text/html )
spring.thymeleaf.content-type=text/html
# 开启 MVC Thymeleaf 视图解析(默认值: true )
spring.thymeleaf.enabled=true
# 模板编码
spring.thymeleaf.encoding=UTF-8
# 要被排除在解析之外的视图名称列表,⽤逗号分隔
spring.thymeleaf.excluded-view-names=
# 要运⽤于模板之上的模板模式。另⻅ StandardTemplate-ModeHandlers( 默认值: HTML5)
spring.thymeleaf.mode=HTML5
# 在构建 URL 时添加到视图名称前的前缀(默认值: classpath:/templates/ )
spring.thymeleaf.prefix=classpath:/templates/
# 在构建 URL 时添加到视图名称后的后缀(默认值: .html )
spring.thymeleaf.suffix=.html
编写一个Controller
@Controller
public class TestController {
@GetMapping("/test")
public String hello(Model model){
model.addAttribute("msg", "你好Thymeleaf");
return "hello";
}
}
编写页面hello.html解析
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<p>[[${msg}]]p>
<p th:text="${msg}">p>
body>
html>
[[${}]]
适用于 追加文本
th:text=""
适用于 替换文本
变量表达式即OGNL表达式或Spring EL表达式(在Spring术语中也叫model attributes)。
语法格式:${表达式}
如下所示:
${session.user.name}
<span th:text="${book.author.name}">
<li th:each="book : ${books}">
@RequestMapping("/expression-var")
public String expression(Model model) {
// 普通数据类型
model.addAttribute("MyName", "张三");
model.addAttribute("MyAge", 20);
// 对象数据类型
Student student = new Student();
student.setId(1001);
student.setName("yaml");
student.setEmail("[email protected]");
student.setAge(21);
model.addAttribute("student", student);
// 引用数据类型
Schools school = new Schools();
school.setSchoolName("到北小学");
school.setSchoolAddress("陕西咸阳");
student.setSchool(school);
model.addAttribute("student2",student);
return "var1";
}
<p th:text="${MyName}">p>
<p th:text="${MyAge}">p>
<p>用户名:<span th:text="${student.name}">span>p>
<p>用户id:<span th:text="${student.id}">span>p>
<p>用户年龄:<span th:text="${student.age}">span>p>
<p>用户邮箱:<span th:text="${student.email}">span>p>
<p>用户学校名称:<span th:text="${student2.school.schoolName}">span>p>
<p>用户学校地址:<span th:text="${student2.school.schoolAddress}">span>p>
选择表达式很像变量表达式,不过它们用一个预先选择的对象来代替上下文变量容器(map)来执行,如下:
*{customer.name}
被指定的object由th:object属性定义:
<div th:object="${book}">
...
<span th:text="*{title}">...</span>
...
</div>
文字国际化表达式允许我们从一个外部文件获取区域文字信息(.properties),用Key索引Value,还可以提供一组参数(可选).
#{main.title}
#{message.entrycreated(${entryId})}
可以在模板文件中找到这样的表达式代码:
<table>
...
<th th:text="#{header.address.city}">...</th>
<th th:text="#{header.address.country}">...</th>
...
</table>
创建一个资源文件用来提供国际化的模板提供
英文
login=login
中文
login=登录
编写一个配置文件
public class MyLocalResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
String lang = request.getParameter("lang");
Locale locale = request.getLocale();
if (!StringUtils.isEmpty(lang)) {
String[] data = lang.split("_");
locale = new Locale(data[0], data[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
}
}
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver(){
return new MyLocalResolver();
}
}
@RequestMapping("/i18n")
public String i18n(Model model){
return "login";
}
URL表达式指的是把一个有用的上下文或回话信息添加到URL,这个过程经常被叫做URL重写。
@{/order/list}
URL还可以设置参数:
@{/order/details(id=${orderId})}
相对路径:
@{../documents/report}
让我们看这些表达式:
<form th:action="@{/createOrder}"><a href="main.html" th:href="@{/main}">
{/} 是相对应用的根,即网页上下文
如果不考虑上下文的情况下,两者没有区别;星号语法评估在选定对象上表达,而不是整个上下文
什么是选定对象?就是父标签的值,如下:
<div th:object="${session.user}">
<p>Name: <span th:text="*{firstName}">Sebastianspan>.p>
<p>Surname: <span th:text="*{lastName}">Pepperspan>.p>
<p>Nationality: <span th:text="*{nationality}">Saturnspan>.p>
div>
这是完全等价于:
<div th:object="${session.user}">
<p>Name: <span th:text="${session.user.firstName}">Sebastianspan>.
p><p>Surname: <span th:text="${session.user.lastName}">Pepperspan>.
p><p>Nationality: <span th:text="${session.user.nationality}">Saturnspan>.p>
div>
当然,美元符号和星号语法可以混合使用:
<div th:object="${session.user}">
<p>Name: <span th:text="*{firstName}">Sebastianspan>.p>
<p>Surname: <span th:text="${session.user.lastName}">Pepperspan>.p>
<p>Nationality: <span th:text="*{nationality}">Saturnspan>.p>
div>
小例子:
public class HelloThymeleaf {
public static void main(String[] args) {
// 创建模板引擎
TemplateEngine engine = new TemplateEngine();
// 准备模板
String input = "";
// Context 准备数据
Context context = new Context();
// 调用引擎 处理数据 和模板、
String str = engine.process(input, context);
System.out.println("结果数据:"+str);
}
}
<h2>文本使用h2>
<p th:text="学习文本表达式">文本处理p>
<p th:text="'hello thymeleaf'">用空格的文本p>
<p th:text="'学习'+${info}">连接字符串+p>
<p th:text="'学习'+'java'">连接字符串+p>
<p th:text="|您好 ${info}|">连接字符串+p>
<p th:text="|${n1},${n2}|+'你好'">连接字符串+p>
<p th:text="123">数字文本p>
<p th:text="true">布尔文本p>
<p th:text="${n1}">p>
<p th:text="${n2}">p>
注意:如果表达式中的字串有空格 空格
需要配使用单引号 或者|xxx|
,连接字串需要使用+
号拼接
<span>字面常量数字1+1:span><p th:text="1+1">p><hr>
<span>表达式的算数${n1}+${n2}:span><p th:text="${n1}+${n2}">p><hr>
<span>表达式结合的算术${n1}+1:span><p th:text="${n1}+1">p><hr>
<span>有字符串穿插的算术和运算1+1+'字符串'+2+4:span><p th:text="1+1+'字符串'+2+4">p>
<hr>
<span>括号提高优先级和运算1+1+'字符串'+(2+4):span><p th:text="1+1+'字符串'+(3+4)">p>
<hr>
<p th:text="true">显示truep>
<p th:if="${marriage}">已婚,能看到标签么p>
<p th:if="${age} < 20">您未成年p>
<p th:if="${age} > 20">您成年p>
<p th:if="${marriage} and ${age} > 18">符合法定结婚年龄 已婚p>
**注意:如果需要使用逻辑表达式 需要使用 and or **
null字面量在页面中可以直接使用 也可以作为判断的依据是否为null 但数据为null式时,标签和内容不显示。同理”“空字串处理结果也一样。
创建一个NullController
@RequestMapping("/null")
public String doNull(Model model){
model.addAttribute("null", null);
model.addAttribute("emptys", "");
return "null";
}
模板展示
<h2>空字符的使用h2>
<p th:if="${null} == null">这是一个空p>
<p th:if="${emptys} == ''">这是一个空字串p>
<p th:text="${null}">null值p>
<p th:text="''">空字串p>
<p th:text="null">null值p>
需要用到th:if
的标签
<p th:if="10>5">10大于5p>
<p th:if="10 > 5">10大于6p>
<p th:if="10 < 12">10大于12p>
<p th:if="10 < 13">10大于13p>
<p th:if="10 == 10">10等于10p>
<p th:if="10 eq 10">10等于10p>
<p th:if="not(false)">非假p>
<p th:if="${isLogin}">登录成功p>
<p th:if="!${isLogin}">未登录p>
<p th:text="10>5?'10大于5':'10不大于5'">p>
<p th:text="${age}>20?'age大于20':'age不大于20'">p>
<p th:text="${age}!=null?'age是'+${age}:'age是null'">p>
<p th:text="${age}!=null?(${age}>30?'age大于30':'age不够30'):'age是null'">p>
三元表达式是可以嵌套使用的
属性 | 作用 |
---|---|
th:text | 计算其值表达式并将结果设置为标签的标签体 |
th:utext | th:text 会对结果中的特殊字符转义,th:utext则不会转义 |
th:attr | 为标签中的任意属性设置,可以一次为多个属性赋值 |
th:* | 为html指定的属性设置,一次设置一个 |
th:alt-title | 同时为alt与title属性赋值 |
th:lang-xmllang | 同时为lang、xml:lang属性赋值 |
th:fragment | 定义模板片段 |
th:insert | 将被引用的模板片段插入到自己的标签体中(完全插入) |
th:replace | 将被引用的模板片段替换掉自己的 |
th:include | 类似于th:insert 而不是插入片段 不推荐使用(只插入文本内容) |
th:remove | 删除模板中的某些代码片那 |
th:each | 迭代数据 如 数组 list map等 |
th:if | 条件为true显示模板片段 否则不显示 |
th:unless | 条件为false 显示模板片段 否则不显示 |
th:switch | 与Java中的switch语句等效 有条件的显示匹配的内容 |
th:case | 配合switch使用 |
th:with | 定义局部变量 |
th:inline | 禁用内联表达式,内联js、css |
th:attr 语法不优雅 可以使用th:value、th:action、th:href等替换
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:lang-xmllang="en">
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript">
function fun1() {
alert(111)
}
</script>
<style>
.large-font{
font-size: 20px;
color: red;
}
</style>
</head>
<body>
<form action="/hello.html" method="post" th:attr="action=${MyAction}">
账号:<input type="text" name="username">
密码:<input type="password" name="password">
<input type="submit" th:attr="value=${mytext}">
<input type="button" value="点我" th:attr="οnclick='fun1()'">
</form>
<a href="" th:class="large-font">超链接</a>
<image th:src="@{../static/image/1.jpg}" th:title="${mytext}" th:alt-title="我的最爱"></image>
</body>
</html>
如果设置成了true则对应的属性值为显示相应的属性值 否则不显示
model.addAttribute("selected", true);
model.addAttribute("unselect", false);
<input type="checkbox" value="游泳" th:checked="${selected}">游泳 <br>
<input type="checkbox" value="骑行" th:checked="${unselect}">骑行 <br>
@RequestMapping("/txt")
public String adTxt(Model model) {
model.addAttribute("msg","学习开发语言Java");
model.addAttribute("context","学习开发语言MySQL,Vue,SpringBoot");
return "body";
}
html
<p th:text="${msg}">p>
<p th:utext="${context}">p>
类似于jstl里面的c:forEach
特点:
<tr th:each=“成员遍历:${表达式}”>
<td th:text="${成员}">td>
tr>
@RequestMapping("/each")
public String doEach(Model model) {
List<Employee> list = new ArrayList<>();
list.add(new Employee(1, "占山", 21));
list.add(new Employee(2, "李四", 51));
list.add(new Employee(3, "王五", 45));
list.add(new Employee(4, "赵六", 15));
list.add(new Employee(5, "孙七", 34));
list.add(new Employee(6, "刘能", 54));
list.add(new Employee(7, "谢广坤", 23));
model.addAttribute("emp",list);
return "body";
}
<h3>遍历集合h3>
<table border="1" cellspacing="0" cellpadding="0">
<thead>
<tr>
<td>编号td>
<td>姓名td>
<td>年龄td>
tr>
thead>
<tr th:each="e : ${emp}">
<td th:text="${e.id}">td>
<td th:text="${e.name}">td>
<td th:text="${e.age}">td>
tr>
table>
Map<String, Employee> map = new HashMap<>();
map.put("1", new Employee(1, "占山", 21));
map.put("2", new Employee(2, "李四", 51));
map.put("3", new Employee(3, "王五", 45));
map.put("4", new Employee(4, "赵六", 15));
map.put("5", new Employee(5, "孙七", 34));
map.put("6", new Employee(6, "刘能", 54));
model.addAttribute("maps", map);
注意:map集合是一个键不能为空,值可以为空的一个容器,键重复则覆盖
<h3>遍历Maph3>
<table border="1" cellspacing="0" cellpadding="0">
<thead>
<tr>
<td>编号td>
<td>姓名td>
<td>年龄td>
tr>
thead>
<tr th:each="e : ${maps}">
<td th:text=" ${e.key}">td>
<td th:text=" ${e.value.name}">td>
<td th:text=" ${e.value.age}">td>
tr>
table>
@RequestMapping("/listMap")
public String doListMap(Model model) {
List
<h3>循环ListMaph3>
<ul th:each=" lm : ${listMap}">
<li th:each="entry : ${lm}" th:text="${entry.key}">li>
<li th:each="entry : ${lm}" th:text="${entry.value}">li>
ul>
String[] arr = {"张飞","刘备","关羽"};
model.addAttribute("arr", arr);
<h3>遍历数组h3>
<ul>
<li th:each="name : ${arr}" th:text="${name}">li>
ul>
Map<String, String> cities = new HashMap<>();
cities.put("010", "天津");
cities.put("020", "湖南");
cities.put("030", "陕西");
cities.put("040", "上海");
model.addAttribute("cities", cities);
model.addAttribute("selected", true);
<h3>遍历下拉列表h3>
<select name="" id="" >
<option th:value="'--请选择城市--'" th:text="'--请选择城市--'" th:selected="${selected}">option>
<option th:each="city:${cities}" th:value="${city.key}" th:text="${city.value}">option>
select>
语法格式:
<tr th:each="循环变量,状态变量 : ${表达式}">
<td th:text="状态变量名.状态值">td>
tr>
<h3>遍历集合h3>
<table border="1" cellspacing="0" cellpadding="0">
<thead>
<tr>
<td>编号td>
<td>姓名td>
<td>年龄td>
<td>循环状态循环的次数counttd>
<td>循环状态循环的当前元素currenttd>
<td>循环状态当前迭代的计数sizetd>
<td>循环状态firsttd>
<td>循环状态lasttd>
<td>循环状态eventd>
<td>循环状态oddtd>
tr>
thead>
<tr th:each="e,loopStatus : ${emp}">
<td th:text="${e.id}">td>
<td th:text="${e.name}">td>
<td th:text="${e.age}">td>
<td th:text="'总计循环数据共'+${loopStatus.count}+'条'">td>
<td th:text="'当前循环的数据'+${loopStatus.current}">td>
<td th:text="'总计循环数据共'+${loopStatus.size}+'条'">td>
<td th:text="${loopStatus.first}?'是第一条数据':'不是第一个数据'">td>
<td th:text="${loopStatus.last}?'是最后一条数据数据':'不是最后一条数据数据'">td>
<td th:text="${loopStatus.even}?'是偶数行':'是奇数行'">td>
<td th:text="${loopStatus.odd}?'是奇数行':'是偶数行'">td>
tr>
table>
演示:
@RequestMapping("/iftest")
public String doIf(Model model) {
// 真的
model.addAttribute("old", "true");
model.addAttribute("login", "login");
model.addAttribute("bool", true);
model.addAttribute("num1", 12);
model.addAttribute("num2", -2);
model.addAttribute("old", 0);
model.addAttribute("str0", "");
model.addAttribute("object", new Student());
// 假的
model.addAttribute("marriage", "false");
model.addAttribute("falseflag", false);
model.addAttribute("Stroff", "off");
model.addAttribute("Strno", "no");
return "if";
}
<h3>为真判断h3>
<p th:if="true">判断是否true,truep>
<p th:if="'true'">判断是否字串true,"true"p>
<p th:if="99">判断是数字,99p>
<p th:if="${old}">oldp>
<p th:if="${str0}">空字串p>
<hr>
<h3>为假的判断h3>
<p th:if="${marriage}">结婚了p>
<p th:if="${Stroff}">offp>
<p th:if="${Strno}">nop>
不满足的条件显示,否则不显示,略
公用的重复的每个页面都是的时候,公共资源,可重复使用使用的资源可以定义为模板
模板的使用
<div th:fragement="模板名称">
模板内容
div>
insert
**<div th:insert="模板所在的我呢见名称::模板名称">
其他内容
div>
replace
**<div th:replace="模板所在的我呢见名称::模板名称">
其他内容
div>
<div th:remove="删除范围值">
div>
范围值:
首先定义模板内容
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div th:fragment="header">
<b>学习thymeleaf语法b>
div>
<div th:fragment="copy">
© 权限归魏永鹏所有 2020-2022
div>
<div th:fragment="funtpl(one,two)">
<p th:text="'hello'+${one}+','+${two} ">p>
div>
body>
html>
模板引用
<body>
<p>使用Header名称的模板p>
<div th:insert="fragement/footer::header">
插入header名称模板
div>
body>
在插入 模板的时候还可以使用~
这种语法来进行插入,效果与insert一致
语法如下:
<footr>
<p>页脚p>
<div th:insert="fragement/footer::copy">div>
<div th:insert="~{fragement/footer::copy}">div>
footr>
函数模板的引用
<h3>参数模板的使用h3>
<div th:insert="fragement/footer::funtpl(one='张三',two='李四')">
参数模板的使用
div>
当前页面引用模板
<div th:fragment="course">
这是一个当前页面的模板
div>
<h3>引用当前页面的模板h3>
<div th:insert="::course">div>
<div th:insert="~{::course}">div>
id引用模板
这是一个当前页面的模板2 使用id定义的模板
使用dom对象的id引用模板
<div th:fragment="dram1">
这是一个自定义的模板
div>
<p>引用模板dram1p>
<div th:insert="::dram1">div>
<hr>
<div th:remove="all">
<span>1111span>
<ul>
<li>1li>
<li>2li>
ul>
div>
<hr>
<div th:remove="body">
<span>1111span>
<ul>
<li>1li>
<li>2li>
ul>
div>
<hr>
<div th:remove="tag">
<span>1111span>
<ul>
<li>1li>
<li>2li>
ul>
div>
<hr>
<div th:remove="all-but-first">
<span>1111span>
<ul>
<li>1li>
<li>2li>
ul>
div>
<hr>
<div th:remove="none">
<span>1111span>
<ul>
<li>1li>
<li>2li>
ul>
div>
需要在thymeleaf表达式写到标签体中,而不是写道标签内,可以使用内联语法
语法格式:
[[…]]或者[(…)]内敛表达式在任何th:text或者th:utext属性中使用的表达式都可以出现在[[]],[()]中使用
即[[]]或者[()]可以替换掉th:text或者th:utext
- [[]]等效替换th:text
- [()]等效替换th:utext
【语法格式】
<p th:inline="none">原样输出的内容p>
【语法格式】
<script type="text/javascript" th:inline="javascript">script>
@RequestMapping("/inline")
public String doInline(Model model) {
List<Employee> list = new ArrayList<>();
list.add(new Employee(1, "张三", 21));
list.add(new Employee(2, "李四", 25));
list.add(new Employee(3, "王五", 34));
model.addAttribute("name", "刘备");
model.addAttribute("list", list);
return "inline";
}
html页面使用js
<script th:inline="javascript" type="text/javascript">
var list = [[${list}]];
var name = [[${name}]];
console.log(name);
for (var i = 0; i < list.length; i++) {
console.log(list[i])
}
script>
如果要在js内敛中使用tymeleaf语法,则必须指定标签内为th:inline=‘javascript’
内联的优点:可以在标签内添加非模型数据
th:with定义的变量只能在该声明的标签内使用
@RequestMapping("/var")
public String doVar(Model model) {
model.addAttribute("name","李四2");
return "var";
}
<div th:with="name='张三'">
<p>局部变量:[[${name}]]p>
div>
<p>全局设置的request域中的name值:[[${name}]]p>
#uris
内置对象<body th:with="myUrl='http://localhost:8080/myWeb/hello.jsp?username=张三'">
模板名称:<p th:text="${#execInfo.templateName}">p>
模板模式:<p th:text="${#execInfo.templateMode}">p>
<div th:with="espath=${#uris.escapePath(myUrl)}">
编码的值:[[${espath}]]<br>
解码的值:[[${#uris.unescapePath(espath)}]]<br>
div>
#dates
内置对象<h3>格式化日期h3>
<p>原始日期:[[${myDate}]]p>
<p>解析后的日期:[[${#dates.format(myDate,'yyyy-MM-dd HH:mm:ss')}]]p>
#unmbers
内置对象<h3>格式化数字h3>
<p>原始数字:[[${price}]]p>
<p>解析后的数字:[[${#numbers.formatInteger(price,0)}]]p>
<p>解析后的数字:[[${#numbers.formatInteger(price,3)}]]p>
<p>解析后的数字:[[${#numbers.formatDecimal(price,3,1)}]]p>
参数解析:
#strings
内置对象<h3>格式化字符串h3>
<p>原始字符串:[[${myName}]]p>
<p>myName是否为空:[[${#strings.isEmpty(myName)}]]p>
<p>解析后的字符串:[[${#strings.substring(myName,0,3)}]]p>
<p>包含key的索引:[[${#strings.indexOf(myName,'key')}]]p>
<p>包含kep的索引:[[${#strings.indexOf(myName,'kep')}]]p>
<p>转大写:[[${#strings.toUpperCase(myName)}]]p>
@RequestMapping("/scope")
public String doScope(Model model, HttpServletRequest request) {
model.addAttribute("myName","keppys");
request.setAttribute("myName2", "jakson");
request.getSession().setAttribute("sessionName", "jerry");
request.getSession().getServletContext().setAttribute("applicationName", "offer");
return "scope";
}
<p>request1:[[${myName}]]p>
<p>request2:[[${myName2}]]p>
<p>session:[[${session.sessionName}]]p>
<p>context:[[${application.applicationName}]]p>
静态资源:https://wwa.lanzoui.com/iGD3xl6i5ni
新建一个SpringBoot项目,引入核心的Thymeleaf依赖
将静态资源放入到static目录下,将所有的页面文件放入到templates目录下。
这里我只完成一个简单的登录功能
导入login.html,index.html,将index.html改名为main.html
编写控制层,使用Thymeleaf语法在html页面实现登陆的跳转
// 去登陆页
@GetMapping(value = {"/", "/login"})
public String loginPage() {
return "login";
}
// 登录请求
@PostMapping(value = "/login")
public String main(User user, HttpSession session, Model model) {
// 这块可以写一些数据库账号密码的逻辑操作
// ...
// 如果密码账号无误,ok登录 把登录信息放到Session作用域中
// 这里只做非空判断
if (!StringUtils.isEmpty(user.getUsername()) && user.getPassword().equalsIgnoreCase("123456")) {
// 保存登陆成功的用户
session.setAttribute("loginUser", user);
return "redirect:/main.html";
} else {
model.addAttribute("msg", "账号密码错误");
return "login";
}
}
// 解决表单重复提交 重定向
@GetMapping("/main.html")
public String mainPage(HttpSession session, Model model) {
// 判断登录
Object loginUser = session.getAttribute("loginUser");
if (loginUser != null) {
return "main";
} else {
model.addAttribute("msg", "您未登录,请先登录在访问");
return "login";
}
}
Login.html中表单的action属性替换为Thymeleaf语法th:action=”@{/login}“
<form class="form-signin" th:action="@{/login}" method="post">
...
form>
Thymeleaf还可以在JavaScript脚本中使用,在JS中使用就需要用到
[[${}]]
的语法来获取域中的值。
<script type="text/javascript">
const msg = '[[${msg}]]';
console.log(msg);
if (msg == "账号密码错误") {
alert(msg)
}
script>