SpringBoot页面展示Thymeleaf

文章目录

Thymeleaf

官网
开发传统Java WEB工程时,我们可以使用JSP页面模板语言,但是在SpringBoot中已经不推荐使用了。SpringBoot支持如下页面模板语言
Thymeleaf
FreeMarker
Velocity
Groovy
JSP
上面并没有列举所有SpringBoot支持的页面模板技术。其中Thymeleaf是SpringBoot官方所推荐使用的,下面来谈谈Thymeleaf一些常用的语法规则。

Thymeleaf模板既能用于web环境下,也能用于非web环境下,在非web环境下,它能直接显示模板上的静态数据,在web环境下,它能像JSP一样从后台接收数据并替换掉模板上的静态数据;

Thymeleaf 它是基于HTML的,以HTML标签为载体,Thymeleaf 要寄托在HTML的标签下实现对数据的展示;

thymeleaf是另外的一种模板技术,它本身并不属于springboot,springboot只是很好地集成这种模板技术,作为前端页面的数据展示;

springboot中的集成

添加Thymeleaf依赖

要想使用Thhymeleaf,首先要在pom.xml文件中单独添加Thymeleaf依赖。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Thymeleaf 在 SpringBoot 中的配置大全:

#spring.thymeleaf.cache = true #启用模板缓存。

#spring.thymeleaf.check-template = true #在呈现模板之前检查模板是否存在。

#spring.thymeleaf.check-template-location = true #检查模板位置是否存在。

#spring.thymeleaf.content-type = text/html #Content-Type值。

#spring.thymeleaf.enabled = true #启用MVC Thymeleaf视图解析。

#spring.thymeleaf.encoding = UTF-8 #模板编码。

#spring.thymeleaf.excluded-view-names = #应该从解决方案中排除的视图名称的逗号分隔列表。

#spring.thymeleaf.mode = HTML5 #应用于模板的模板模式。另请参见StandardTemplateModeHandlers。

#spring.thymeleaf.prefix = classpath:/templates/ #在构建URL时预先查看名称的前缀。

#spring.thymeleaf.suffix = .html #构建URL时附加到查看名称的后缀。

#spring.thymeleaf.template-resolver-order = #链中模板解析器的顺序。

#spring.thymeleaf.view-names = #可以解析的视图名称的逗号分隔列表。

#开发阶段,建议关闭thymeleaf的缓存
spring.thymeleaf.cache=false
#使用遗留的html5以去掉对html标签的校验
spring.thymeleaf.mode=LEGACYHTML5

在使用springboot的过程中,如果使用thymeleaf作为模板文件,则要求HTML格式必须为严格的html5格式,必须有结束标签,否则会报错;

如果不想对标签进行严格的验证,使用spring.thymeleaf.mode=LEGACYHTML5去掉验证,去掉该验证,则需要引入如下依赖,否则会报错:

<dependency>
    <groupId>net.sourceforge.nekohtml</groupId>
    <artifactId>nekohtml</artifactId>
</dependency>

<dependency>
    <groupId>org.unbescape</groupId>
    <artifactId>unbescape</artifactId>
    <version>1.1.5.RELEASE</version>
</dependency>

NekoHTML是一个Java语言的 HTML扫描器和标签补全器 ,这个解析器能够扫描HTML文件并“修正”HTML文档中的常见错误。
NekoHTML能增补缺失的父元素、自动用结束标签关闭相应的元素,修复不匹配的内嵌元素标签等;
注意: springboot默认已经配置了springMvc视图解析器

springboot中的应用

HTML页面的元素中加入以下属性:

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

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Spring boot集成 Thymeleaf</title>
</head>
<body>
<p th:text="${data}">Spring boot集成 Thymeleaf</p>
</body>
</html>

html写入位置

Spring Boot默认存放模板页面的路径在src/main/resources/templates或者src/main/view/templates,这个无论是使用什么模板语言都一样,当然默认路径是可以自定义的,不过一般不推荐这样做。另外Thymeleaf默认的页面文件后缀是.html。
所以在springboot自动生成的项目中有resources/templates这个文件夹,我们一般用这个.因为springboot底层已经做好的视图的映射 templates文件夹表示html的根路径
在这里插入图片描述
在controller中的操作

在这里插入图片描述

thymeleaf变量表达式

引入连接

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
	<meta charset="UTF-8">
	<base th:href="${#request.getContextPath()}+'/'">
	<link rel="shortcut icon" th:href="@{/personstyle/images/ico/favicon.ico}">
	<link rel="stylesheet" type="text/css" th:href="@{/css/font-awesome.min.css}">
	<link rel="stylesheet" type="text/css" th:href="@{/css/iconfont.css}">
	<link rel="stylesheet" type="text/css" th:href="@{/jquery-easyui/themes/black/easyui.css}">
	<link rel="stylesheet" type="text/css" th:href="@{/jquery-easyui/themes/icon.css}">

	<!-- 本项目公用顶层样式  勿删 -->
	<link rel="stylesheet" th:href="@{/personstyle/css/base.css}">
	<!-- 自定义css -->
	<link rel="stylesheet" th:href="@{/personstyle/css/all_style.css}">


	<script type="text/javascript" charset="UTF-8" th:src="@{/jquery-easyui/jquery.min.js}"></script>
	<script type="text/javascript" charset="UTF-8" th:src="@{/jquery-easyui/jquery.easyui.min.js}"></script>
	<script type="text/javascript" charset="UTF-8" th:src="@{/jquery-easyui/locale/easyui-lang-zh_CN.js}"></script>
	<script type="text/javascript" charset="UTF-8" th:src="@{/personstyle/js/echarts.min.js}"></script>
	<script type="text/javascript" charset="UTF-8" th:src="@{/personstyle/js/common.js}"></script>
	<script type="text/javascript" charset="UTF-8" th:src="@{/personstyle/js/flv.js}"></script>
	<script type="text/javascript" charset="UTF-8" th:src="@{/personstyle/js/VideoControl.js}"></script>

	<title>监控报警</title>
</head>

base

<base th:href="${#request.getContextPath()}+'/'">

在js中显示

var userId = [[${userId}]];

数据的展示全部寄托在html标签中

thymeleaf所有的数据表达式均是html每个标签元素中,依靠标签来展示数据,不能单独使用.
这是与JSTL不一样的地方

标准变量表达式

语法${}

<span th:text="${user.nick}">默认数据</span>
<span th:text="${user.phone}">默认数据</span>
<span th:text="${user.email}">默认数据</span>
<span th:text="${user.address}">默认数据</span>

th:text="" 是Thymeleaf的一个属性,用于文本的显示;
如果${}能获取到数据则展示thymeleaf中的数据 否则展示默认数据

选择变量表达式

语法:*{…}
选择变量表达式,也叫星号变量表达式,使用 th:object 属性来绑定对象.
比如:页面接收一个user实体类

<div th:object="${user}" >
    <p>nick: <span th:text="*{nick}"></span></p>
    <p>phone: <span th:text="*{phone}" ></span></p>
    <p>email: <span th:text="*{email}" >北京</span></p>
    <p>address: <span th:text="*{address}" >北京</span></p>
</div>

选择表达式首先使用th:object来邦定后台传来的User对象,然后使用 * 来代表这个对象,后面 {} 中的值是此对象中的属性;

选择变量表达式 *{…} 是另一种类似于变量表达式 ${…} 表示变量的方法;

选择变量表达式在执行时是在选择的对象上求解,而${…}是在上下文的变量Model上求解;

上面的代码等价于:

<div>
    <p>nick: <span th:text="${user.nick}"></span></p>
    <p>phone: <span th:text="${user.phone}" ></span></p>
    <p>email: <span th:text="${user.email}" >北京</span></p>
    <p>address: <span th:text="${user.address}" >北京</span></p>
</div>

标准变量表达式和选择变量表达式可以混合一起使用比较灵活,比如:

<div th:object="${user}" >
    <p>nick: <span th:text="*{nick}"></span></p>
    <p>phone: <span th:text="${user.phone}" ></span></p>
    <p>email: <span th:text="${user.email}" >北京</span></p>
    <p>address: <span th:text="*{address}" >北京</span></p>
</div>

也可以不使用 th:object 进行对象的选择,而直接使用 *{…} 获取数据,比如:

<div>
    <p>nick: <span th:text="*{user.nick}"></span></p>
    <p>phone: <span th:text="*{user.phone}" ></span></p>
    <p>email: <span th:text="*{user.email}" >北京</span></p>
    <p>address: <span th:text="*{user.address}" >北京</span></p>
</div>

URL表达式

语法:@{…}
URL表达式可用于

1、绝对URL,比如:
<a href="info.html" th:href="@{'http://localhost:8080/boot/user/info?id='+${user.id}}">查看</a>
2、相对URL,相对于页面,比如:
<a href="info.html" th:href="@{'user/info?id='+${user.id}}">查看</a>
3、相对URL,相对于项目上下文,比如:
<a href="info.html" th:href="@{'/user/info?id='+${user.id}}">查看</a> (项目的上下文名会被自动添加)

Thymeleaf常见属性展示

th:action

定义后台控制器的路径,类似标签的action属性,比如:

<form id="login" th:action="@{/login}">......</form>
th:each(重点)

这个属性非常常用,比如从后台传来一个对象集合那么就可以使用此属性遍历输出,它与JSTL中的<c: forEach>类似,此属性既可以循环遍历集合,也可以循环遍历数组及Map,比如:

<tr th:each="user, interStat : ${userlist}">
    <td th:text="${interStat.index}"></td>
    <td th:text="${user.id}"></td>
    <td th:text="${user.nick}"></td>
    <td th:text="${user.phone}"></td>
    <td th:text="${user.email}"></td>
    <td th:text="${user.address}"></td>
</tr>

th:each=“user, iterStat : ${userlist}” 中的 u s e r L i s t 是 后 台 传 来 的 K e y , u s e r 是 {userList} 是后台传来的Key, user是 userListKeyuser{userList} 中的一个数据,
iterStat 是 ${userList} 循环体的信息,
其中user及iterStat自己可以随便写;
interStat是循环体的信息,通过该变量可以获取如下信息:
index、size、count、even、odd、first、last,其含义如下:
index: 当前迭代对象的index(从0开始计算)
count: 当前迭代对象的个数(从1开始计算)
size: 被迭代对象的大小
current: 当前迭代变量
even/odd: 布尔值,当前循环是否是偶数/奇数(从0开始计算)
first: 布尔值,当前循环是否是第一个
last: 布尔值,当前循环是否是最后一个

注意:循环体信息interStat也可以不定义,则默认采用迭代变量加上Stat后缀,即userStat

Map类型的循环:
<div th:each="myMapVal : ${myMap}">
    <span th:text="${myMapVal.key}"></span>
    <span th:text="${myMapVal.value}"></span>
    <br/>
</div>

m y M a p V a l . k e y 是 获 取 m a p 中 的 k e y , {myMapVal.key} 是获取map中的key, myMapVal.keymapkey{myMapVal.value} 是获取map中的value;

数组类型的循环:
<div th:each="myArrayVal : ${myArray}">
    <div th:text="${myArrayVal}"></div>
</div> 
th:href

定义超链接,比如:

<a  class="login" th:href="@{/login}">登录</a>
th:id

类似html标签中的id属性,比如:

<span th:id="${hello}">aaa</span>
th:if

条件判断,比如后台传来一个变量,判断该变量的值,1为男,2为女:

<span th:if="${sex} == 1" >
	男:<input type="radio" name="se"  th:value="" />
</span>
<span th:if="${sex} == 2">
	女:<input type="radio" name="se" th:value=""  />
</span>
th:unless

th:unless是th:if的一个相反操作,上面的例子可以改写为:

<span th:unless="${sex} == 1" >
	女:<input type="radio" name="se"  th:value="" />
</span>
<span th:unless="${sex} == 2">
	男:<input type="radio" name="se" th:value=""  />
</span>
th:switch/th:case

switch,case判断语句,比如:

<div th:switch="${sex}">
  <p th:case="1">性别:男</p>
  <p th:case="2">性别:女</p>
  <p th:case="*">性别:未知</p>
</div>

一旦某个case判断值为true,剩余的case则都当做false,“*”表示默认的case,前面的case都不匹配时候,执行默认的case;

th:object

用于数据对象绑定

通常用于选择变量表达式(星号表达式)
th:src

用于外部资源引入,比如

<script th:src="@{/static/js/jquery-2.4.min.js}"></script>
<img th:src="@{/static/image/logo.png}"/>
th:text 和th:utext

th:utext和th:text的区别是:th:text会对<和>进行转义,而th:utext不会转义。

<input type="text" id="realName" name="reaName" th:text="${realName}">
th:value

类似html标签中的value属性,能对某元素的value属性进行赋值,比如:

<input type="hidden" id="userId" name="userId" th:value="${userId}">
th:attr

该属性也是用于给HTML中某元素的某属性赋值,但该方式写法不够优雅,比如上面的例子可以写成如下形式:

<input type="hidden" id="userId" name="userId" th:attr="value=${userId}" >

Thymeleaf字面量

文本字面量

用单引号’…'包围的字符串为文本字面量,比如:

<a th:href="@{'api/getUser?id=' + ${user.id}}">修改</a>
数字字面量
<p>今年是<span th:text="2017">1949</span></p>
<p>20年后, 将是<span th:text="2017 + 20">1969</span></p>
boolean字面量

true和false

<p th:if="${isFlag} == false">
false在花括号外面,解析识别由Thymleaf自身完成
</p>

<p th:if="${isFlag == true}">
false写在花括号里面,解析识别由SpringEL完成
</p>
null字面量
<p th:if="${userlist == null}">
userlist为空
</p>

<p th:if="${userlist != null}">
userlist不为空
</p>

Thymeleaf 字符串拼接

一种是字面量拼接:
<a href="#" th:text="''+${sex}+'页 ,共'+${sex}+''"></a>
另一种更优雅的方式,使用“|”减少了字符串的拼接:
<a href="#" th:text="|第${sex}页,共${sex}页|"></a>

Thymeleaf 三元运算判断

<span th:text="${sex eq '1'} ? '' : ''">未知</span>

Thymeleaf 运算和关系判断

算术运算:+ , - , * , / , %
关系比较: > , < , >= , <= ( gt , lt , ge , le )
相等判断:== , != ( eq , ne )

Thymaleaf 表达式基本对象

1、模板引擎提供了一组内置的对象,这些内置的对象可以直接在模板中使用,这些对象由#号开始引用:
2、官方手册:http://t.cn/RHsbZpk
#ctx:上下文对象

#vars:上下文变量

#locale: 上下文语言环境.

#httpServletRequest: (仅在web上下文)相当于HttpServletRequest 对象,这是2.x版本,若是3.x版本使用 #request;

#httpSession: (仅在web上下文)相当于HttpSession 对象,这是2.x版本,若是3.x版本使用#session; 需要在后台controller中设置了session

Thymaleaf 表达式功能对象

1、模板引擎提供的一组功能性内置对象,可以在模板中直接使用这些对象提供的功能方法:
2、工作中常使用的数据类型,如集合,时间,数值,可以使用thymeleaf的提供的功能性对象来解析他们;
3、内置功能对象前都需要加#号,内置对象一般都以s结尾;

日期格式化
#dates: java.util.Date对象的实用方法,<span th:text="${#dates.format(curDate, 'yyyy-MM-dd HH:mm:ss')}"></span>

#calendars: 和dates类似, 但是 java.util.Calendar 对象;

#numbers: 格式化数字对象的实用方法;

#strings: 字符串对象的实用方法: contains, startsWith, prepending/appending等;

#objects: 对objects操作的实用方法;

#bools: 对布尔值求值的实用方法;

#arrays: 数组的实用方法;

#lists: list的实用方法,比如

#sets: set的实用方法;

#maps: map的实用方法;

#aggregates: 对数组或集合创建聚合的实用方法;

操作内置对象

虽然在这种模版开发框架里面是不提倡使用内置对象的,但是很多情况下依然需要使用内置对象进行处理,所以下面来看下如何在页面中使用JSP内置对象。

1在控制器里面增加一个方法,这个方法将采用内置对象的形式传递属性。
@RequestMapping(value = "/inner", method = RequestMethod.GET)
public String inner(HttpServletRequest request, Model model) {
    request.setAttribute("requestMessage", "springboot-request");
    request.getSession().setAttribute("sessionMessage", "springboot-session");
    request.getServletContext().setAttribute("applicationMessage",
            "springboot-application");
    model.addAttribute("url", "www.baidu.cn");
    request.setAttribute("url2",
            "<span style='color:red'>www.baidu.cn</span>");
    return "show_inner";
}
2在页面之中如果要想访问不同属性范围中的内容,则可以采用如下的做法完成:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>SpringBoot模版渲染</title>
    <script type="text/javascript" th:src="@{/js/main.js}"></script> 
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
</head>
<body>
    <p th:text="${#httpServletRequest.getRemoteAddr()}"/>
    <p th:text="${#httpServletRequest.getAttribute('requestMessage')}"/>
    <p th:text="${#httpSession.getId()}"/>
    <p th:text="${#httpServletRequest.getServletContext().getRealPath('/')}"/>
    <hr/>
    <p th:text="'requestMessage = ' + ${requestMessage}"/>
    <p th:text="'sessionMessage = ' + ${session.sessionMessage}"/>
    <p th:text="'applicationMessage = ' + ${application.applicationMessage}"/>
</body>
</html>

thymeleaf 考虑到了实际的开发情况,因为 request 传递属性是最为常用的,但是 session 也有可能使用,例如:用户登录之后需要显示用户 id,那么就一定要使用到 session,所以现在必须增加属性范围的形式后才能够正常使用。在 thymeleaf 里面也支持有 JSP 内置对象的获取操作,不过一般很少这样使用。

逻辑处理

所有的页面模版都存在各种基础逻辑处理,例如:判断、循环处理操作。在 Thymeleaf 之中对于逻辑可以使用如下的一些运算符来完成,例如:and、or、关系比较(>、<、>=、<=、==、!=、lt、gt、le、ge、eq、ne)。

通过控制器传递一些属性内容到页面之中:
<span th:if="${member.age lt 18}">
未成年人!
</span>
<span th:if="${member.name eq '啊三'}">
欢迎小三来访问!
</span>
不满足条件的判断
<span th:unless="${member.age gt 18}">
你还不满18岁,不能够看电影!
</span>
通过swith进行分支判断
<span th:switch="${member.uid}">
<p th:case="100">uid为101的员工来了</p>
<p th:case="99">uid为102的员工来了</p>
<p th:case="*">没有匹配成功的数据!</p>
</span>

数据遍历

在实际开发过程中常常需要对数据进行遍历展示,一般会将数据封装成list或map传递到页面进行遍历操作。

1定义控制器类,向页面传递List数据和Map数据
@Controller
public class UserController {
    @RequestMapping(value = "/user/map", method = RequestMethod.GET)
    public String map(Model model) {
        Map<String,User> allMembers = new HashMap<String,User>();
        for (int x = 0; x < 10; x++) {
            User vo = new User();
            vo.setUid(101L + x);
            vo.setName("赵四 - " + x);
            vo.setAge(9);
            vo.setSalary(99999.99);
            vo.setBirthday(new Date());
            allMembers.put("mldn-" + x, vo);
        }
        model.addAttribute("allUsers", allMembers);
        return "user_map";
    }

    @RequestMapping(value = "/user/list", method = RequestMethod.GET)
    public String list(Model model) {
        List<User> allMembers = new ArrayList<User>();
        for (int x = 0; x < 10; x++) {
            User vo = new User();
            vo.setUid(101L + x);
            vo.setName("赵四 - " + x);
            vo.setAge(9);
            vo.setSalary(99999.99);
            vo.setBirthday(new Date());
            allMembers.add(vo) ;
        }
        model.addAttribute("allUsers", allMembers);
        return "user_list";
    }
}
2list类型数据遍历
<body>
    <table>
        <tr><td>No.</td><td>UID</td><td>姓名</td><td>年龄</td><td>偶数</td><td>奇数</td></tr>
        <tr th:each="user,memberStat:${allUsers}">
            <td th:text="${memberStat.index + 1}"/>
            <td th:text="${user.uid}"/>
            <td th:text="${user.name}"/>
            <td th:text="${user.age}"/>
            <td th:text="${memberStat.even}"/>
            <td th:text="${memberStat.odd}"/>
        </tr>
    </table>
</body>
3map类型数据遍历
<body>
    <table>
        <tr><td>No.</td><td>KEY</td><td>UID</td><td>姓名</td><td>年龄</td><td>偶数</td><td>奇数</td></tr>
        <tr th:each="memberEntry,memberStat:${allUsers}">
            <td th:text="${memberStat.index + 1}"/>
            <td th:text="${memberEntry.key}"/>
            <td th:text="${memberEntry.value.uid}"/>
            <td th:text="${memberEntry.value.name}"/>
            <td th:text="${memberEntry.value.age}"/>
            <td th:text="${memberStat.even}"/>
            <td th:text="${memberStat.odd}"/>
        </tr>
    </table>
</body>

页面引入

我们常常需要在一个页面当中引入另一个页面,例如,公用的导航栏以及页脚页面。thymeleaf中提供了两种方式进行页面引入。

th:replace
th:include

1新建需要被引入的页面文件,路径为"src/main/view/templates/commons/footer.html"
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<footer th:fragment="companyInfo">
    <p>设为首页 ©2018 SpringBoot 使用<span th:text="${projectName}"/>前必读
        意见反馈 京ICP030173</p>
</footer>

可以看到页面当中还存在一个变量projectName,这个变量的值可以在引入页面中通过th:with="projectName=百度"传过来。

<div th:include="@{/commons/footer} :: companyInfo" th:with="projectName=百度"/>

thymeleaf:字符串Strings常见的使用方法

==判断是不是为空:null: ==

<span th:if="${name} != null">不为空</span> 
<span th:if="${name1} == null">为空</span> 

==判断是不是为空字符串: “” ==

<span th:if="${#strings.isEmpty(name1)}">空的</span> //为空
<img th:if="${not #strings.isEmpty(path)}" th:src="${path}" class="layui-nav-img">//不为空弄个

==判断是否相同: ==

<span th:if="${name} eq 'jack'">相同于jack,</span> 
<span th:if="${name} eq 'ywj'">相同于ywj,</span> 
<span th:if="${name} ne 'jack'">不相同于jack,</span> 

不存在设置默认值:

<span th:text="${name2} ?: '默认值'"></span> 

是否包含(分大小写):

<span th:if="${#strings.contains(name,'ez')}">包ez</span> 
<span th:if="${#strings.contains(name,'y')}">包j</span> 

是否包含(不分大小写)

<span th:if="${#strings.containsIgnoreCase(name,'y')}">包j</span> 

${#strings.startsWith(name,‘o’)}
${#strings.endsWith(name, ‘o’)}
${#strings.indexOf(name,frag)}// 下标
${#strings.substring(name,3,5)}// 截取
${#strings.substringAfter(name,prefix)}// 从 prefix之后的一位开始截取到最后,比如 (ywj,y) = wj, 如果是(abccdefg,c) = cdefg//里面有2个c,取的是第一个c
${#strings.substringBefore(name,suffix)}// 同上,不过是往前截取
${#strings.replace(name,‘las’,‘ler’)}// 替换
${#strings.prepend(str,prefix)}// 拼字字符串在str前面
${#strings.append(str,suffix)}// 和上面相反,接在后面
${#strings.toUpperCase(name)}
${#strings.toLowerCase(name)}
${#strings.trim(str)}
${#strings.length(str)}
${#strings.abbreviate(str,10)}// 我的理解是 str截取0-10位,后面的全部用…这个点代替,注意,最小是3位

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值