SpringBoot集成Thymeleaf模板引擎

一.Thymeleaf 简介

Thymeleaf 是一个跟 Velocity、FreeMarker 相似的模板引擎,它能够彻底替代 JSP 。相较与其余的模板引擎,它有以下三个极吸引人的特色

  1. Thymeleaf 在有网络和无网络的环境下皆可运行,即它可让美工在浏览器查看页面的静态效果,也可让程序员在服务器查看带数据的动态页面效果。这是因为它支持 html 原型,而后在 html 标签里增长额外的属性来达到模板 + 数据的展现方式。浏览器解释 html 时会忽略未定义的标签属性,因此 thymeleaf 的模板能够静态地运行;当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示。
  2. Thymeleaf 开箱即用的特性。它提供标准和 Spring 标准两种方言,能够直接套用模板实现 JSTL、 OGNL 表达式效果,避免天天套模板、改 JSTL、改标签的困扰。同时开发人员也能够扩展和建立自定义的方言。
  3. Thymeleaf 提供 Spring 标准方言和一个与 SpringMVC 完美集成的可选模块,能够快速的实现表单绑定、属性编辑器、国际化等功能。

二.Spring Boot 与 Thymeleaf

若是但愿以 Jar 形式发布模块则尽可能不要使用 JSP 相关知识,这是由于 JSP 在内嵌的 Servlet 容器上运行有一些问题 (内嵌 Tomcat、 Jetty 不支持 Jar 形式运行 JSP,Undertow 不支持 JSP)。javascript

Spring Boot 中推荐使用 Thymeleaf 做为模板引擎,由于 Thymeleaf 提供了完美的 Spring MVC 支持css

Spring Boot 提供了大量模板引擎,包括html

  • FreeMarker
  • Groovy
  • Mustache
  • Thymeleaf
  • Velocity
  • Beetl(很强大,完爆上面全部的引擎)

三.第一个 Thymeleaf 模板页


  1. 新建一个名为 spring-boot-thymeleaf 的 Spring Boot 项目,并引入 Thymeleaf 的 starter pom
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
     
    这里的依赖记得后面添加上去,这里的依赖是非严格的html5的依赖,使用它以后咱们对未w3c的文件严格度会下降
    <dependency>
        <groupId>net.sourceforge.nekohtml</groupId>
        <artifactId>nekohtml</artifactId>
        <version>1.9.22</version>
    </dependency>
  2. 在 application.yml 中配置属性解析器(复制便可)
    # Thymeleaf Start
    spring:
      thymeleaf:
        cache: false # 开发时关闭缓存,否则无法看到实时页面
        mode: LEGACYHTML5 # 用非严格的 HTML
        encoding: UTF-8
        content-type: text/html
    # Thymeleaf End
  3. 演示页面

    根据默认原则,页面应该放置在 src/main/resources/templates 下,在该目录下新建 index.html前端

    <!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta content="text/html;charset=UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width-device-width, initial-scale=1" />
        <link th:src="@{bootstrap/css/bootstrap.min.css}" rel="stylesheet" />
        <link th:src="@{bootstrap/css/bootstrap-theme.min.css}" rel="stylesheet" />
    </head>
    <body>
    <div class="panel panel-primary">
        <div class="panel-heading">
            <h3 class="panel-title">访问 model</h3>
            <div class="panel-body">
                <span th:text="${singlePerson.name}" />
            </div>
        </div>
    </div>
    
    <div class="panel panel-primary">
        <div class="panel-heading">
            <h3 class="panel-title">列表</h3>
            <div class="panel-body">
                <ul class="list-group">
                    <li class="list-group-item" th:each="person:${people}">
                        <span th:text="${person.name}"></span>
                        <span th:text="${person.age}"></span>
                        <button class="btn" th:onclick="'getName(\'' + ${person.name} + '\');'">得到名字</button>
                    </li>
                </ul>
            </div>
        </div>
    </div>
    
    <script th:src="@{jquery.min.js}" type="text/javascript"></script>
    <script th:src="@{bootstrap/js/bootstrap.min.js}" type="text/javascript"></script>
    <script th:inline="javascript">
        var single = [[${singlePerson}]];
        console.log(single.name + "/" + single.age);
    
        function getName(name) {
            console.log(name)
        }
    </script>
    </body>
    </html>
  4. 脚本样式静态文件html5

    根据默认原则,脚本样式、图片等静态文件应该放置在 src/main/resources/static 下,这里引入 Bootstrap 和 jQueryjava

  5. 示例 JavaBeanjquery

    此类用来在模板页面展现数据用,包含 name 和 age 属性程序员

    package com.example.springbootthymeleaf.entity;
    
    public class Student {
        
        private String name;
        private Integer age;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    }
  6. 数据准备web

    package com.example.springbootthymeleaf.controller;
    
    import com.example.springbootthymeleaf.entity.Student;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import java.util.ArrayList;
    import java.util.List;
    
    @Controller
    public class IndexController {
        List<Student> stuList = new ArrayList<Student>();
    
        public void init(){
            Student stu1 = new Student();
            stu1.setName("张三");
            stu1.setAge(18);
            Student stu2 = new Student();
            stu2.setName("李四");
            stu2.setAge(18);
            Student stu3 = new Student();
            stu3.setName("张三");
            stu3.setAge(18);
            stuList.add(stu1);
            stuList.add(stu2);
            stuList.add(stu3);
        }
    
        @RequestMapping("/toIndex")
        public String toIndex(Model model){
            init();
            model.addAttribute("stuList" , stuList);
            return "index";
        }
    
    }
  7. 测试运行spring

 

四.Thymeleaf 经常使用语法

  1. 引入 Thymeleaf

    修改 html 标签用于引入 thymeleaf 引擎,这样才能够在其余标签里使用 th:* 语法,这是下面语法的前提。

    <!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
  2. 获取变量值
    <p th:text="'Hello!, ' + ${name} + '!'" >name</p>

    能够看出获取变量值用 $ 符号,对于javaBean的话使用 变量名.属性名 方式获取,这点和 EL 表达式同样.

    另外 $ 表达式只能写在th标签内部,否则不会生效,上面例子就是使用 th:text 标签的值替换 p 标签里面的值,至于 p 里面的原有的值只是为了给前端开发时作展现用的.这样的话很好的作到了先后端分离.

  3. 引入 URL

    Thymeleaf 对于 URL 的处理是经过语法 @{…} 来处理的

    <a th:href="@{http://www.baidu.com}">绝对路径</a>
    <a th:href="@{/}">相对路径</a>
    <a th:href="@{css/bootstrap.min.css}">Content路径,默认访问static下的css文件夹</a>

    相似的标签有:th:href 和 th:src

  4. 字符串替换

    不少时候可能咱们只须要对一大段文字中的某一处地方进行替换,能够经过字符串拼接操做完成:

    <span th:text="'Welcome to our application, ' + ${user.name} + '!'">

    一种更简洁的方式是:

    <span th:text="|Welcome to our application, ${user.name}!|">
    固然这种形式限制比较多,|…|中只能包含变量表达式${…},不能包含其余常量、条件表达式等。
  5. 运算符

    在表达式中可使用各种算术运算符,例如+, -, *, /, %

    th:with="isEven=(${prodStat.count} % 2 == 0)"

    逻辑运算符>, <, <=,>=,==,!=均可以使用,惟一须要注意的是使用<,>时须要用它的HTML转义符:

    th:if="${prodStat.count} &gt; 1"
    th:text="'Execution mode is ' + ( (${execMode} == 'dev')? 'Development' : 'Production')"
  6. 条件
    • if/unless

      Thymeleaf 中使用 th:if 和 th:unless 属性进行条件判断,下面的例子中,标签只有在 th:if 中条件成立时才显示:

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

      th:unless 于 th:if 刚好相反,只有表达式中的条件不成立,才会显示其内容。

    • switch

      Thymeleaf 一样支持多路选择 Switch 结构:

      <div th:switch="${user.role}">
        <p th:case="'admin'">User is an administrator</p>
        <p th:case="#{roles.manager}">User is a manager</p>
      </div>

      默认属性 default 能够用 * 表示:

      <div th:switch="${user.role}">
        <p th:case="'admin'">User is an administrator</p>
        <p th:case="#{roles.manager}">User is a manager</p>
        <p th:case="*">User is some other thing</p>
      </div>
  7. 循环

    渲染列表数据是一种很是常见的场景,例如如今有 n 条记录须要渲染成一个表格,该数据集合必须是能够遍历的,使用 th:each 标签:

    <body>
      <h1>Product list</h1>
     
      <table>
        <tr>
          <th>NAME</th>
          <th>PRICE</th>
          <th>IN STOCK</th>
        </tr>
        <tr th:each="prod : ${prods}">
          <td th:text="${prod.name}">Onions</td>
          <td th:text="${prod.price}">2.41</td>
          <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
        </tr>
      </table>
     
      <p>
        <a href="../home.html" th:href="@{/}">Return to home</a>
      </p>
    </body>

    能够看到,须要在被循环渲染的元素(这里是)中加入 th:each 标签,其中 th:each="prod : ${prods}" 意味着对集合变量 prods 进行遍历,循环变量是 prod 在循环体中能够经过表达式访问。

相关文章
相关标签/搜索