thymeleaf使用

Thymeleaf是什么?

Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP 。从代码层次上讲:Thymeleaf是一个java类库,他是一个xml/xhtml/html5的模板引擎,可以作为mvc的web应用的view层。

为什么要使用thymeleaf?

  1. jsp目录结构繁琐,页面不简介,不能打包成jar 内置jetty不支持jsp

  2. thymeleaf开箱即用,提供标准和spring标准的两种方言。可以直接套用模板实现jstl,ognl表达式

  3. thymeleaf提供spring标准方言和一个与SpringMvc完美集成的可选模块,可以快速实现表的绑定,属性编辑器,国际化等功能

  4. 可以直接编写html,美工页面可以直接拿来用

  5. Spring-boot支持FreeMarker、Thymeleaf、jsp、veocity 。但是对freemarker和thymeleaf的支持最好,不推荐使用jsp

使用Thymeleaf

  1. 导入springboot依赖spring-boot-starter-thymeleaf

  2. 在application.properties或者applicantion.yml中配置

spring:
  thymeleaf:
    prefix: classpath:/templates/
    check-template-location: true
    cache: false
    suffix: .html
    encoding: UTF-8
    content-type: text/html
    mode: HTML5
    #prefix:指定模板所在的目录
    #check-tempate-location: 检查模板路径是否存在
    #cache: 是否缓存,开发模式下设置为false,避免改了模板还要重启服务器,线上设置为true,可以提高性能。
    #encoding&content-type:这个大家应该比较熟悉了,与Servlet中设置输出对应属性效果一致。
    #mode:这个还是参考官网的说明吧,并且这个是2.X与3.0不同。

thymeleaf语法

  1. 可以在spring框架的jar包中找到autofigure下的thymeleaf属性类找到配置默认路径和默认后缀

  2. 在controller中方法返回String类型,即默认的teamplates下html的文件名(不带后缀)

th属性

  1. th:text当前元素的文本内容(不会转义成html标签),th:utext会转义成html标签

  2. th:value设置当前元素的value值,类似修改还有th:src(编定js的文件路径使用链接表达式@{}),th:href(link文件路径,也是用链接表达式)

  3. th:each 循环遍历元素,通常和th:text和th:value一起使用

  4. th:if 条件判断。类似还有 th:unless th:switch th:case

  5. th:insert 代码块引入,类似的还有th:replace th:include三者区分比较大。使用不当会破坏html结构

  6. th:fragment 定义代码块,方便被th:insert引用

  7. th:object 声明变量。一般和*{}配合使用

  8. th:atrr 修改任意属性,实际开发中使用比较少

使用thymeleaf使用要注意一下几点

  1. 首先要声明名称空间xmlns:th="http://www.thymeleaf.org"

  2. 设置文本内容 th:text

  3. 设置input的值th:value

  4. 循环输出 th:each

  5. 条件判断th:if

  6. 插入代码块 th:insert

  7. 定义代码块 th:fragment

  8. 声明变量th:object

  9. th:each 用法需要注意,循环哪个标签,th:each 就要放到哪个标签上面

  10. 变量表达式有很多内置的方法 比如 #strings.isEmpty 不要与#{}混淆

案例

@Controller
//定义控制层,返回数据
public class ThController {
    @RequestMapping("/success")
    public String success(Model model){
        //1.绑定一个字符串
        model.addAttribute("msg","this is a <b>String</b>");
        model.addAttribute("msgUtext","this is a <b>String</b>");
         //2.绑定一个pojo对象--先去创建一个Emp
        Emp emp=new Emp("张三",20);
        model.addAttribute("emp",emp);
    
        //3.绑定一个list
        List list=new ArrayList();
        list.add(emp);
        list.add(new Emp("李四",20));
        list.add(new Emp("王五",20));
        model.addAttribute("emps",list);
    
        //4.绑定一个map
        Map<String,Object> map=new HashMap<>();
        map.put("Boss",new Emp("boss",30));
        model.addAttribute("map",map);
    
        //前缀:classpath:/templates/ success  后缀.html
        return "success";
    }
}

首先声明命名空间

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

<body>
<h1>this is success.html</h1>
<!--th:text 设置当前元素的文本内容,常用,优先级不高-->
<p th:text="${msg}"></p>
<p th:utext="${msgUtext}"></p>
 
<!--th:value 设置当前元素的value值,常用,优先级仅比th:text高-->
姓名:<input type="text" th:value="${emp.name}" />
年龄:<input type="text" th:value="$emp.name"/>年龄:<inputtype="text"th:value="{emp.name}" />
年龄:<input type="text" th:value="
emp.name"/>年龄:<inputtype="text"th:value="{emp.age}" />
</body>
<!--th:each 遍历列表,常用,优先级很高,仅此于代码块的插入,遍历被修饰的元素-->
<table border="1px" th:width="200px">
    <thead>
        <tr>
            <th>编号</th>
            <th>姓名</th>
            <th>年龄</th>
            <th>操作</th>
        </tr>
    </thead>
    <tbody>
            <!--使用th:each 时,使用 e:${} 绑定对象名-->
        <tr th:each="e:${emps}">
            <td>编号</td>
            <td th:text="${e.name}"></td>
            <td th:text="${e.age}"></td>
            <td>删除/修改</td>
        </tr>
    </tbody>
    <tbody>

   estate属性包括
   index:列表状态的序号,从0开始;
    count:列表状态的序号,从1开始;
    size:列表状态,列表数据条数;
    current:列表状态,当前数据对象
    even:列表状态,是否为奇数,boolean类型
    odd:列表状态,是否为偶数,boolean类型
    first:列表状态,是否为第一条,boolean类型
    last:列表状态,是否为最后一条,boolean类型
<tr th:each="e,eState:${emps}">
    <td th:text="${eState.index+1}"></td>
    <td th:text="${e.name}"></td>
    <td th:text="${e.age}"></td>
    <td>删除/修改</td>
</tr> 
<p th:text="${map.Boss.name}" th:if="${map.Boss.age gt 20}"></p>

表达式

  1. ${…} 变量表达式

    可以获取对象的属性和方法

    可以使用 ctx vars locale request reponse session servletContext

    可以使用 dates numbers strings objects arrays lists sets maps

    ctx :上下文对象。

    vars :上下文变量。

    locale:上下文的语言环境。

    request:(仅在web上下文)的 HttpServletRequest 对象。

    response:(仅在web上下文)的 HttpServletResponse 对象。

    session:(仅在web上下文)的 HttpSession 对象。

    servletContext:(仅在web上下文)的 ServletContext 对象

    java 代码将用户名放在session中

    session.setAttribute("userinfo",username);

    Thymeleaf通过内置对象直接获取

    th:text="${session.userinfo}"

    常见方法

    strings:字符串格式化方法,常用的Java方法它都有。比如:equals,equalsIgnoreCase,length,trim,toUpperCase,toLowerCase,indexOf,substring,replace,startsWith,endsWith,contains,containsIgnoreCase等

    numbers:数值格式化方法,常用的方法有:formatDecimal等

    bools:布尔方法,常用的方法有:isTrue,isFalse等

    arrays:数组方法,常用的方法有:toArray,length,isEmpty,contains,containsAll等

    listssets:集合方法,常用的方法有:toList,size,isEmpty,contains,containsAll,sort等

    maps:对象方法,常用的方法有:size,isEmpty,containsKey,containsValue等

    dates:日期方法,常用的方法有:format,year,month,hour,createNow等

    <h3>#strings </h3> 
    //绑定一个字符串
     model.addAttribute("itdragonStr","this is a DEMO");
    <div th:if="${not #strings.isEmpty(itdragonStr)}" >
        <p>Old Str : <span th:text="${itdragonStr}"/></p>
        <p>toUpperCase : <span th:text="${#strings.toUpperCase(itdragonStr)}"/></p>
        <p>toLowerCase : <span th:text="${#strings.toLowerCase(itdragonStr)}"/></p>
        <p>equals : <span th:text="${#strings.equals(itdragonStr, 'itdragonblog')}"/></p>
        <p>equalsIgnoreCase : <span th:text="${#strings.equalsIgnoreCase(itdragonStr, 'itdragonblog')}"/></p>
        <p>indexOf : <span th:text="${#strings.indexOf(itdragonStr, 'r')}"/></p>
        <p>substring : <span th:text="${#strings.substring(itdragonStr, 2, 8)}"/></p>
        <p>replace : <span th:text="${#strings.replace(itdragonStr, 'it', 'IT')}"/></p>
        <p>startsWith : <span th:text="${#strings.startsWith(itdragonStr, 'it')}"/></p>
        <p>contains : <span th:text="${#strings.contains(itdragonStr, 'IT')}"/></p>
    </div>
    
  2. @{…} 链接表达式

@{。。} 链接表达式不管式静态资源的引用,form表单的请求,凡事用@{、、。}.都可以动态获取项目路径,即使项目名字变了,依旧可以正常访问

需要在application.yml 中修改项目名字,链接表达式会自动修改路径 server.context-path=/nsk

链接表达式结构

无参数:@{/xxx}

有参数 @{/xxx(k1=v1,k2=v2)} =>>/xxx?k1=v1&&k2=v2

引入本地资源 @{/xx/xx}

引入外部资源 @{/webjars/xxx}

<!--引入外部资源-->
<link th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}" rel="stylesheet">
 
<!--引入本地资源-->
<link th:href="@{/main/css/itdragon.css}" rel="stylesheet">
 
<!--表单提交路径-->
<form class="form-login" th:action="@{/user/login}" th:method="post" >
 
<!--超链接跳转路径附带参数-->
<a class="btn btn-sm" th:href="@{/login.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/login.html(l='en_US')}">English</a>

  1. #{。。} 消息表达式

    #{。。}消息表达式 结构 th:text=“#{msg}”

  2. ~{。。} *{…} 代码块表达式

  3. 推荐:~{templatename::fragmentname}

    支持:~{templatename::#id}

    templatename:模版名,Thymeleaf会根据模版名解析完整路径:/resources/templates/templatename.html,要注意文件的路径。

    fragmentname:片段名,Thymeleaf通过th:fragment声明定义代码块,即:th:fragment=“fragmentname”

    id:HTML的id选择器,使用时要在前面加上#号,不支持class选择器。