SpringBoot整合Thymeleaf

743 阅读3分钟


Thymeleaf、 freemarker用于网页静态化,Thymeleaf 是Java服务端的模板引擎,与传统的JSP不同,Thymeleaf 可以使用浏览器直接打开,相当于打开html原生页面。


1. 基本使用

1)导入依赖

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

</dependency>




2)修改配置文件

在src/main/java/resources/application.properties配置如下信息:

##########
配置
thymeleaf ##########

spring.thymeleaf.cache=false
spring.thymeleaf.encoding
=utf-8

spring.thymeleaf.prefix=classpath:/templates

spring.thymeleaf.suffix=.html

spring.thymeleaf.mode=HTML5
spring.thymeleaf.servlet.content-type=text/html




3)创建controller

package com.qf.controller;    import org.springframework.stereotype.Controller;  import org.springframework.ui.Model;  import org.springframework.web.bind.annotation.RequestMapping;    
  @Controller
@RequestMapping("/thymeleaf")  public class ThymeleafController {      @RequestMapping("/hello")    public String hello(Model model){          System.out.println("hello thymeleaf");    
        model.addAttribute("hello","hello thymeleaf !");          return "/thymeleaf";    }    
}



4)在templates目录下创建thymeleaf.html

<!DOCTYPE html><html lang="en" xmlns:th="http://www.w3.org/1999/xhtml"><head>    <meta charset="UTF-8">    
    <title>Title</title></head><body>    
    <h1 th:text="${hello}">测试内容</h1>    
</body>    
</html>



5)访问controller进行测试



2. 常用标签应用

1)导入lombok依赖

<dependency>    <groupId>org.projectlombok</groupId>    <artifactId>lombok</artifactId></dependency>



2)创建User实体类

package com.qf.entity;

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

import java.util.Date;


@Data

@AllArgsConstructor
@NoArgsConstructor
public class User {

private Integer id;

private String username;
private String password;
private Date birthday;


}




3)在Controller层添加查询所有User

@RequestMapping("/findAll")  public String findAll(Model model){      ArrayList<User> users = new ArrayList<>();
    users.add(new User(1001,"张三","123",new Date()));    users.add(new User(1002,"李四","456",new Date()));    users.add(new User(1003,"王五","789",new Date()));    
    model.addAttribute("users",users);    
    return "/list";}




4)在templates目录下创建list.html

<!DOCTYPE html><html lang="en" xmlns:th="http://www.w3.org/1999/xhtml"><head>    <meta charset="UTF-8">    <title>Title</title></head><body>    
<div th:if="${users!=null}">    
    <table border="1" width="600">        <tr th:each="user,state : ${users}">
            <td th:text="${state.count}"></td>
            <td th:text="${user.id}"></td>
            <td th:text="${user.username}"></td>            <td th:text="${#dates.format(user.birthday, 'yyyy-MM-dd HH:mm:ss')}"></td>
        </tr>
    </table>    
    <hr>    <table border="1" width="600">    
        <!-- 第二个变量,可以获取遍历的元素的状态-->    
        <tr th:each="user,state : ${users}">            <td th:text="${state.index}"></td>
            <td th:text="${user.id}"></td>            <td th:text="${user.username}"></td>            <td th:text="${#dates.format(user.birthday, 'yyyy-MM-dd HH:mm:ss')}"></td>        </tr>
    </table>    <hr>    
 
    <table border="1" width="600">    
        <!--如果不设置表示状态的变量,默认遍历的元素的变量名+Stat 
表示状态的变量-->        <tr th:each="user : ${users}">
            <td th:text="${userStat.count}"></td>
            <td th:text="${user.id}"></td>    
            <td th:text="${user.username}"></td>
            <td th:text="${#dates.format(user.birthday, 'yyyy-MM-
dd HH:mm:ss')}"></td>    
        </tr>    </table>    
</div>    
<hr color="red">
 
<table border="1" width="600">    
 
    <tr>
        <th>序号</th>
        <th>姓名</th>        <th>生日</th>        <th>详情</th>    
    </tr>    <tr th:each="user : ${users}">
        <td th:text="${userStat.count}"></td>        <td th:text="${user.username}"></td>        <td th:text="${#dates.format(user.birthday, 'yyyy-MM-dd HH:mm:ss')}"></td>        <td><a th:href="@{/thymeleaf/findById(uid=${user.id})}">查询</a></td>    
    </tr></table></body>
</html>



5)在Controller层添加查询单个User

@RequestMapping("/findById")
public String findById(Model model,String uid){

System.

out
.println(uid);

if(uid.equals("1001")){

User user = new User(1001, "张三", "123", new Date());
model.addAttribute("user",user);

}

return "/queryOne";

}



6)在templates目录下创建queryOne.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form th:object="${user}">
<input type="hidden" th:id="*{id}" name="id">
用户名:<input type="text" th:value="*{username}" name="username" /><br /><br />
密码:<input type="text" th:value="*{password}" name="password"/>
</form>

</body>
</html>











常用th:前缀的属性

关键字   功能介绍     案例

th:id   替换id      <input th:id="'xxx' + ${collect.id}"/>

th:text  文本替换     <p th:text="${collect.description}">description</p>

th:utext 支持html的文本替换 <p th:utext="${htmlcontent}">conten</p>

th:object 替换对象     <div th:object="${session.user}">

th:value 属性赋值     <input th:value="${user.name}" />

th:with 变量赋值运算     <div th:with="isEven=${prodStat.count}%2==0"></div>

th:style 设置样式         th:style="'display:' + @{(${sitrue} ? 'none' : 'inline-block')} + ''"

th:onclick 点击事件       th:onclick="'getCollect()'"

th:each 属性赋值         tr th:each="user,userStat:${users}">

th:if 判断条件         <a th:if="${userId == collect.userId}" >

th:unless 和th:if判断相反     <a th:href="@{/login}" th:unless=${session.user != null}>Login</a>

th:href 链接地址           <a th:href="@{/login}" th:unless=${session.user != null}>Login</a> />

th:switch 多路选择 配合th:case 使用 <div th:switch="${user.role}">

th:case th:switch的一个分支     <p th:case="'admin'">User is an administrator</p>

th:fragment 布局标签,定义一个代码片段,方便其它地方引用 <div th:fragment="alert">

th:include 布局标签,替换内容到引入的文件 <head th:include="layout :: htmlhead" th:with="title='xx'"></head> />

th:replace 布局标签,替换整个标签到引入的文件 <div th:replace="fragments/header :: title"></div>

th:selected selected选择框 选中 th:selected="(${xxx.id} == ${configObj.dd})"

th:src 图片类地址引入       <img class="img-responsive" alt="App Logo"

th:src="@{/img/logo.png}" />

th:inline 定义js脚本可以使用变量 <script type="text/javascript" th:inline="javascript">

th:action 表单提交的地址     <form action="subscribe.html" th:action="@{/subscribe}">

th:remove 删除某个属性     <tr th:remove="all">

                    1.all:删除包含标签和所有的孩子。

                    2.body:不包含标记删除,但删除其所有的孩子。

                    3.tag:包含标记的删除,但不删除它的孩子。

                    4.all-but-first:删除所有包含标签的孩子,除了第一个。

                    5.none:什么也不做。这个值是有用的动态评估。

th:attr 设置标签属性,多个属性可以用逗号分隔 比如 th:attr="src=@{/image/aa.jpg},title=#{logo}",此标签不太优雅,一般用的比较少。



















表达式

1)变量表达式${}

获取对象属性,例如:

th:value="${user.id}"
th:text="${info}"


2)选择变量表达式 *{}

先通过th:object 获取对象,然后使用th:xx = "*{}"获取对象属性,一般和form一起使用。

<form id="" th:object="${user}">
<input id="id" name="id" th:value="*{id}"/>
<input id="username" name="username" th:value="*{username}"/>
<input id="password" name="password" th:value="*{password}"/>
</form>

3)链接表达式@{}

通过该表达式引用静态资源路径。例如:

<script th:src="@{/js/jquery/jquery.js}"></script>
<link th:href="@{/bootstrap/css/bootstrap.css}" rel="stylesheet" type="text/css">

注意:/ 表示相对web应用


4)片段表达式 ~{}

片段表达式拥有三种语法:

~{ viewName } 表示引入完整页面

~{ viewName ::selector} 表示在指定页面寻找片段 其中selector可为片段名、jquery选择器等

~{ ::selector} 表示在当前页寻找

首先通过th:fragment定制片段 ,然后通过th:replace 填写片段路径和片段名。例如:

<head th:fragment="static">
<script th:src="@{/webjars/jquery/3.3.1/jquery.js}"></script>
</head>
<div th:replace="~{common/head::static}"></div>

在实际使用中,我们往往使用更简洁的表达,去掉表达式外壳直接填写片段名。例如:

<div th:replace="common/head::static"></div>


5)消息表达式

即通常的国际化属性:#{msg} 用于获取国际化语言翻译值。例如:

<title th:text="#{user.title}"></title>

配置多语言文件的路径和文件前缀

spring.messages.basename=i18n/messages

在resources目录下,新建i18n目录,在该目录下放置多语言文件

多语言文件命名规则:

文件名_语言 _ 国家.properties












内置对象


1)七大基础对象

${#ctx} 上下文对象,可用于获取其它内置对象。

${#vars}: 上下文变量。

${#locale}:上下文区域设置。

${#request}: HttpServletRequest对象。

${#response}: HttpServletResponse对象。

${#session}: HttpSession对象。

${#servletContext}: ServletContext对象。


2)常用的工具类

#strings:字符串工具类

#lists:List 工具类

#arrays:数组工具类

#sets:Set 工具类

#maps:常用Map方法。

#objects:一般对象类,通常用来判断非空

#bools:常用的布尔方法。

#execInfo:获取页面模板的处理信息。

#messages:在变量表达式中获取外部消息的方法,与使用#{...}语法获取的方法相同。

#uris:转义部分URL / URI的方法。

#conversions:用于执行已配置的转换服务的方法。

#dates:时间操作和时间格式化等。

#calendars:用于更复杂时间的格式化。

#numbers:格式化数字对象的方法。

#aggregates:在数组或集合上创建聚合的方法。

#ids:处理可能重复的id属性的方法。



迭代循环

th:each,遍历List集合,例如:

<div th:each="user:${userList}">
账号:<input th:value="${user.username}"/>
密码:<input th:value="${user.password}"/></div>

在集合的迭代过程还可以获取状态变量,只需在变量后面指定状态变量名即可,状

态变量可用于获取集合的下标/序号、总数、是否为单数/偶数行、是否为第一个/最

后一个。例如:

<div th:each="user,stat:${userList}">
下标:<input th:value="${stat.index}"/>

序号:<input th:value="${stat.count}"/>

账号:<input th:value="${user.username}"/>
密码:<input th:value="${user.password}"/>

</div>

如果缺省状态变量名,则迭代器会默认帮我们生成以变量名开头的状态变量 xxStat, 例如:

<div th:each="user:${userList}" >
下标:<input th:value="${userStat.index}"/>

序号:<input th:value="${userStat.count}"/>
账号:<input th:value="${user.username}"/>
密码:<input th:value="${user.password}"/>
</div>



条件判断

条件判断通常用于动态页面的初始化,例如:

<div th:if="${age lt ‘10’}">
<div>haha</div>
</div>

如果想取反则使用unless 例如:

<div th:unless="${age lt ‘10’}">
<div>不存在..</div>
</div>



内联写法

如果需要在 JS中获取服务端返回的变量,格式为:[[${xx}]],该内联表达式仅在页面生效,引入的js文件中使用无效。

<script th:inline="javascript">
var user = [[${user}]];`

var APP_PATH = [[${#request.getContextPath()}]];
var LANG_COUNTRY = [[${#locale.getLanguage()+'_'+#locale.getCountry()}]];
</script>