• 从.Net到Java学习第九篇——SpringBoot下Thymeleaf


    从.Net到Java学习系列目录

    Thymeleaf概述

      Thymeleaf 是一个流行的模板引擎,该模板引擎采用java语言开发。模板引擎是一个技术名称,是跨领域平台的概念,在java语言体系下有模板引擎,在C#、PHP语言体系下也有模板引擎,甚至在JavaScript中也会用到模板引擎技术。
    Java生态下的模板引擎有Thymeleaf 、Freemaker、Velocity、Beetl(国产)等。Thymeleaf模板既能用于web环境下,也能用于非web环境下,在非web环境下,它能直接显示模板上的静态数据,在web环境下,它能像JSP一样从后台接收数据并替换掉模板上的静态数据。.net下面的razor也是一个模板引擎。

    Thymeleaf它是基于HTML的,以HTML标签为载体,Thymeleaf要寄托在HTML的标签下实现对数据的展示。
    Thymeleaf的官方网站:http://www.thymeleaf.org
    Spring boot集成了Thymeleaf模板技术,并且Spring boot官方也推荐使用
    Thymeleaf来替代JSP技术。
    Thymeleaf是另外的一种模板技术,它本身并不属于spring boot,
    srpingboot只是很好的集成了这种模板技术,作为前端页面的数据展示。

    Spring Boot集成Thymeleaf配置

    (1)修改pom.xml,在Maven中引入Thymeleaf的依赖:

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

    (2)在Spring boot的核心配置文件application.yml中对Thymeleaf进行配置:

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

    在使用Spring boot的过程中,如果使用thymeleaf作为模板文件,则要求HTML格式必须为严格的html5格式,所有标签必须有结束标签,否则会报错。如果不想对标签进行严格的验证,使用spring.thymeleaf.model=LEGACYHTML5去掉验证,去掉该验证还需要引入许下的依赖,否则会报错。

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

     (3)新建一个控制器ThymeleafController去映射到模板页

    @Controller
    public class ThymeleafController {
        @GetMapping("/index")
        public String index(Model model){
            model.addAttribute("msg","Spring boot集成Thymeleaf");
            return "index"; //返回的是一个页面,可以省略后缀.html
        }
    }

    (4)在src/main/resources的templates下面新建一个index.html页面用于数据展示,HTML页面的<html>元素中药记得加入以下属性:

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

     index.html源码如下:

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org"><!--引入thymeleaf-->
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <p th:text="${msg}">你好</p>
    </body>
    </html>

     Springboot使用thymeleaf作为视图展示,约定将模板文件放置在src/main/resources/templates目录下,静态资源放置在src/main/resources/static目录下

    运行IDEA项目

    如果不启动spring boot直接在浏览器中浏览这个页面

    Thymeleaf标准变量表达式

    语法:${...}

    变量表达式用于访问容器(tomcat)上下文环境中的变量,功能和JSTL中的${}相同。Thymeleaf中的变量表达式使用${变量名}的方式获取其中的数据。

    新建实体类User

    package com.yujie.entity;
    
    public class User {
        private String name;
        private String sex;
        private Integer age;
        private String email;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    }

    在Spring mvc的Controller中使用向前端传输数据,ThymeleafController代码如下:

        @GetMapping("/user")
        public String user(Model model){
            User user=new User();
            user.setAge(21);
            user.setEmail("zouyujie@126.com");
            user.setName("玉杰");
            model.addAttribute("user",user);
            return "user";
        }

    templates目录下面,新建一个user.html页面,前端接收代码:

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org"><!--引入thymeleaf-->
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <p>用户信息如下:</p>
    <div th:text="${user.name}"></div>
    <div th:text="${user.age}"></div>
    <div th:text="${user.email}"></div>
    </body>
    </html>

    浏览

    选择变量表达式

    选择变量表达式,也叫星号变量表达式,使用th:object属性来绑定对象,比如:

    <p>分割线——选择变量表达式</p>
    <div th:object="${user}">
        <div th:text="*{name}"></div>
        <div th:text="*{age}"></div>
        <div th:text="*{email}"></div>
    </div>

     继续



    选择变量表达式首先使用th:object来绑定后台传来的user对象,然后使用*来代表这个对象,后面{}中的值是此对象中的属性。
    选择变量表达式*{...}是另一种类似于变量表达式${...}表示变量的方法。
    选择变量表达式在执行时是在选择的对象上求解,而${...}是在上下文的变量Model上求解。
    通过th:object属性指明选择变量表达式的求解对象。
    标准变量表达式和选择变量表达式可以混合在一起使用,比如:

    <div th:object="${user}">
        <div th:text="*{name}"></div>
        <div th:text="*{age}"></div>
        <div th:text="${user.email}"></div>
    </div>

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

    <p>不使用th:object</p>
    <div>
        <div th:text="*{user.name}"></div>
        <div th:text="*{user.age}"></div>
        <div th:text="*{user.email}"></div>
    </div>

    Thymeleaf的URL表达式

    语法:@{...}

    URL表达式可用于<script src="...">、<link href="...">、<a href="...">等
    1.绝对URL,比如:

    <a href="index.html" th:href="@{'http://localhost:8080/user?name='+${user.name}}">index</a>

    2.相对URL,相对于页面,比如:

    <a href="index.html" th:href="@{'user?name='+${user.name}}">index</a>

    3.相对URL,相对于项目上下文,比如:

    <a href="index.html" th:href="@{'/user?name='+${user.name}}">index</a>

    项目的上下文名会自动添加,我们可以看下html运行的源码。

    thymeleaf的常用属性

    thymeleaf的常用属性:
    th:action
    th:each
    th:href
    th:id
    th:if
    th:unless
    th:switch/th:case
    th:object
    th:src
    th:text
    th:value
    th:attr
    th:onclick
    th:style
    th:method
    th:name
    th:inline
    这些标记大多数和html的标记名称是一样的。

    thymeleaf表达式基本对象

    模板引擎提供了一组内置的对象,这些内置的对象可以直接在模板中使用,这些对象由#号开始引用。

    #request

    相当于HttpServletRequest对象,这是3.x版本,若是2.x版本使用#httpServletRequest
    ${#request.getContextPath()}
    ${#request.getAttribute("name")}

    #session

    相当于HttpSession
    对象,这是3.x版本,若是2.x版本使用#httpSession,需要在后头controller中设置session,
    ${#session.getAttribute("phone")}
    ${#session.id}

    thymeleaf表达式功能对象

    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:对数组或集合创建聚合的实用方法。

    还有条件表达式等等,更多内容可以参考thymeleaf的官网:http://www.thymeleaf.org

    thymeleaf th:text 不显示标签

    解决办法,通过追加th:remove属性,演示如下:

    <span th:text="${title}" th:remove="tag"></span>

    thymeleaf布局

    thymeleaf既然和razor一样,那么肯定也有布局页,也就是母版页。thymeleaf的layout常用的有两种方式用法:

    第一种 th:include||th:replace||th:insert

    将页面里的每个部分都分成块 -> fragment 使用 th:include 和 th:replace 来引入页面
    这种用法没有layout的概念, 因为每个部分都是 fragment

    • th:insert 3.0+版本新加的
    • th:replace 2.0+ 3.0+都可用
    • th:include 这个在3.0版本已经不建议使用

     它们的区别,

    <footer th:fragment="copy"> 
      © 2011 The Good Thymes Virtual Grocery
    </footer>

    调用方式:

    <!-- 引用html段 --> 
    <body>
    <div th:insert="footer :: copy"></div>
    <div th:replace="footer :: copy"></div>
    <div th:include="footer :: copy"></div>
    </body>

    最终结果如下:

    <!-- 最终结果 --> 
    <body>
    <!-- th:insert,div tag内部插入html段 -->
    <div> <footer> © 2011 The Good Thymes Virtual Grocery </footer> </div>
    <!-- th:replace,使用html段直接替换 div tag -->
    <footer> © 2011 The Good Thymes Virtual Grocery </footer>
    <!-- th:include,div tag内部插入html段(仅保留段子元素的内容) -->
    <!-- 仔细对比 th:insert 与 th:include的结果 -->
    <div> © 2011 The Good Thymes Virtual Grocery </div>
    </body>

     第二种 布局页

    写一个layout.html页面,当作页面的基础页面

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8"/>
        <title>Title</title>
    </head>
    <body>
    <header>这是头部</header>
    <div layout:fragment="content"></div>
    <footer>这是底部</footer>
    </body>
    </html>

    新建一个子页面layoutTest.html,在子页面里使用 layout:decorator 来将子页面里的内容加入到 layout.html里去

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org" layout:decorator="common/layout">
    <head>
        <meta charset="UTF-8"/>
        <title>Title</title>
    </head>
    <body>
    <div layout:fragment="content">
        <h2>我是文本内容</h2>
    </div>
    </body>
    </html>

    控制器中添加一个测试方法

        @RequestMapping("/layout")
        public String layout(Model model) {
            return "layoutTest";
        }

    运行结果如下:

    这样在layout.html里引入的css,js,imgs都可以在子页面里用了,而且在子页面里还可以引入子页面需要用到的css,js,imgs, 就很方便了,所以这也是推荐的方式。
    模板传值,假如要往header.html里传入一个tab来区别应该高亮哪个菜单,可以使用下面的写法实现, 创建header.html,然后在布局页layout.html定一个css样式。

    header.html代码如下:

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8"/>
        <title>Title</title>
    </head>
    <body>
    <header th:fragment="header (tab)">
        <ul>
            <li>
                <span th:class="${tab eq 'news'} ? active">news</span>
            </li>
            <li>
                <span th:class="${tab eq 'blog'} ? active">blog</span>
            </li>
            <li>
                <span th:class="${tab eq 'post'} ? active">post</span>
            </li>
        </ul>
    </header>
    </body>
    </html>

    修改layout.html

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8"/>
        <title>Title</title>
        <style type="text/css">
            .active {background-color: green;}
        </style>
    </head>
    <body>
    <div th:include="common/header :: header(tab='blog')"></div>
    <div layout:fragment="content"></div>
    <footer>这是底部</footer>
    </body>
    </html>

    运行结果如下:

    Spring-Boot配置文件thymeleaf模板配置项(常用配置项为红色

    参数介绍
    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 = 可以解析的视图名称的逗号分隔列表

    参考:https://tomoya92.github.io/2017/03/09/thymeleaf-layout/

  • 相关阅读:
    理解SetCapture、ReleaseCapture、GetCapture(控制了消息发往哪个窗口,是理解消息的关键)
    Javascript 的addEventListener()及attachEvent()区别分析
    鼠标拖拽
    鼠标右键菜单
    keydown
    一串跟随鼠标的DIV
    event对象和事件冒泡
    发表说说
    文档流
    CSS3 @keyframes 规则
  • 原文地址:https://www.cnblogs.com/jiekzou/p/9216305.html
Copyright © 2020-2023  润新知