有勇气的牛排博客

SpringBoot (二) 整合前端模板引擎FreeMarker、thymeleaf

有勇气的牛排 608 Java 2023-02-24 23:26:18

哈喽,大家好,我是有勇气的牛排(全网同名)🐮🐮🐮

有问题的小伙伴欢迎在文末评论,点赞、收藏是对我最大的支持!!!。

文章目录

前言

开发网站的时候,通常会对前后端技术进行选型,前后端分离项目不用多说,正如字面意思,分离开发即可。

但是有些项目需要做SEO优化,这就要使网页静态化,优化速度,提高网站在搜索引擎中的权重,尤其在百度是不支持js加载的页面场景中,页面静态化尤为重要,在Spring开发中,就可以使用模板引擎技术来支撑。

下面主要介绍:FreeMarker与thymeleaf 。

1 整合FreeMarker模板

FreeMark 官网: https://freemarker.apache.org

官方文档:https://freemarker.apache.org/docs/dgui_template_overallstructure.html

Apache FreeMark是一个模板引擎,一个基于模板和变化的数据生成文本输出(HTML网页、电子邮件、配置文件、源代码等)的Java库,模板是用FreeMark模板语言(FTL)编写的,这是一种简单的专用语言。

其逻辑为:
由java计算并提供数据,然后由FreeMark程序结果数据。

并且采用了 MVC (模型、视图、控制器)模式。

image.png

1.1 pom依赖引入

<!-- 模板引擎 引入freeMarker的依赖包. --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>

1.2 yml配置

spring: http: encoding: force: true # 模版引擎编码为UTF-8 charset: UTF-8 # freemarker模板配置 freemarker: allow-request-override: false cache: false check-template-location: true charset: UTF-8 content-type: text/html; charset=utf-8 expose-request-attributes: false expose-session-attributes: false expose-spring-macro-helpers: false ## 模版文件结尾.ftl suffix: .ftl ## 模版文件目录 template-loader-path: classpath:/templates

1.3 后端

FreemarkController.java

/* * @Author : 有勇气的牛排 * @FileName: FreemarkController.java * desc : Freemark模板引擎 * */ package com.couragesteak.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.Map; @Controller public class FreemarkController { // import java.util.Map; // http://127.0.0.1:8080/freemarkIndex @RequestMapping("/freemarkIndex") public String freemarkIndex(Map<String, Object> result, HttpServletRequest request) { System.out.println(666); // 传数据到页面 result.put("name", "有勇气的牛排"); result.put("sex", "0"); result.put("age", 20); ArrayList<Object> tagList = new ArrayList<>(); tagList.add("全程"); tagList.add("解决方案"); result.put("tagList", tagList); return "freemarkIndex"; } }

1.4 前端

<div style="width: 200px;font-weight: 600;"> <div style="border: 1px solid red"> 名字:${name} </div> <div style="border: 1px solid red;margin-top: 10px;"> 性别: <#if sex=="0"> 男 <#elseif sex=="1"> 女 <#else> 未知 </#if> </div> <div style="border: 1px solid red;margin-top: 10px;"> 是否成年: <#if (age>=18)> 成年 <#else> 未成年 </#if> </div> <div style="border: 1px solid red;margin-top: 10px;"> 标签: <#list tagList as tag> ${tag} </#list> </div> </div>

image.png

1.5 模板语法

1.5.1 变量表达式

名字:${name}

1.5.2 list

后端

// list ArrayList<Object> tagList = new ArrayList<>(); tagList.add("全站"); tagList.add("解决方案"); result.put("tagList", tagList);

前端

<#break>: 跳出循环

<#list tagList as tag> <p>${tag}</p> <#break> </#list>

1.5.3 if判断

两种方法
1 用符号代替: > gt , >= gte ,< lt , <= lte
2 加括号 <#if(x>y)>

<#if (age >= 18)> <p>成年</p> <#else> <p>未成年</p> </#if>

1.5.4 include

<#include "include.html"/> <#include "/common/copyright.ftl" encoding="GBK" parse=false/>

1.5.5 switch

<span>4、switch</span> <div> <#switch 1> <#case 3>第3页<#break> <#case 1>第1页<#break> <#case 2>第2页<#break> </#switch> </div>

2 整合 thymeleaf 渲染web页面

thymeleaf是一款用于渲染 xml/xhtml/xhtml5内容的模板引擎,类似于jsp、Velocity、FreeMaker等,它可以轻易的与Spring MVC等web框架进行集成作为 Web应用的模板引擎。

2.1 pom依赖

<!-- 模板引擎 引入thymeleaf的依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>

2.2 yml配置

spring: # ThymeLeaf配置 thymeleaf: #prefix:指定模板所在的目录 prefix: classpath:/templates/ #check-tempate-location: 检查模板路径是否存在 check-template-location: true #cache: 是否缓存,开发模式下设置为false,避免改了模板还要重启服务器,线上设置为true,可以提高性能。 cache: true suffix: .html encoding: UTF-8 mode: HTML5

2.3 java后端

/* * @Author : 有勇气的牛排 * @FileName: ThymeleafController.java * desc : * */ package com.couragesteak.controller; import com.couragesteak.entity.UserEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.Map; @Controller public class ThymeleafController { // http://127.0.0.1:8080/myThymeleaf @RequestMapping("/myThymeleaf") public String myThymeleafController(HttpServletRequest request, Map<String, Object> result) { // request.setAttribute("ruser", new UserEntity("cs", 20)); result.put("user", new UserEntity("cs", 17)); ArrayList<Object> userEntitys = new ArrayList<>(); userEntitys.add(new UserEntity("CS1", 16)); userEntitys.add(new UserEntity("CS2", 20)); result.put("userList", userEntitys); return "myThymeleaf"; } }

2.4 前端

位置:resources/templates

<div> <table> 姓名:<span th:text="${user.userName}"></span> 年龄:<span th:text="${user.age}"></span> </table> <hr> <div> <ul th:each="user:${userList}"> <li> <span th:if="${user.age>= 18}">成年</span> <span th:if="${user.age< 18}">未成年</span> </li> </ul> </div> </div>

image.png

2.5 前端模板语法

  1. th:text: 设置当前元素的文本内容,相同功能的还有th:utext,两者的区别在于前者不会转义html标签,后者会。
  2. th:value: 设置当前元素的value值,类似修改指定html标签属性的还有th:src,th:href。
  3. th:each: 遍历循环元素,和th:text或th:value一起使用。注意该属性修饰的标签位置。
  4. th:if: 条件判断,类似的还有th:unless,th:switch,th:case。
  5. th:insert: 代码块引入,类似的还有th:replace,th:include,常用于公共代码块的提取复用。
  6. th:fragment: 定义代码块,方便被th:insert引用。
  7. th:object: 声明变量,一般和*{}一起配合使用。

th:attr : 修改任意属性,实际开发中用的较少,因为有丰富的其他th属性帮忙。

2.5.1 变量表达式 ${ }

<input type="text" th:value="${user.age}"> <span>三目运算</span> <input type="text" th:value="${user.age>=18?user.age:'未成年'}">
1 内置方法

一、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等
五、lists,sets:集合方法,常用的方法有:toList,size,isEmpty,contains,containsAll,sort等
六、maps:对象方法,常用的方法有:size,isEmpty,containsKey,containsValue等
七、dates:日期方法,常用的方法有:format,year,month,hour,createNow等

2 Map

java

Map myMap = new HashMap(); myMap.put("k1", "大哥"); myMap.put("k2", "牛"); result.put("myMap", myMap);

html

<span>7、Map</span> <div th:if="${not #maps.isEmpty(myMap)}"> <p th:text="${#maps.size(myMap)}"></p> <p th:text="${#maps.containsKey(myMap,'k1')}"></p> <p th:text="${#maps.containsValue(myMap,'K1')}"></p> <p th:text="${myMap.k1}"></p> <p></p> </div>
3 迭代list

后端

ArrayList<Object> userEntitys = new ArrayList<>(); userEntitys.add(new UserEntity("CS1", 16)); userEntitys.add(new UserEntity("CS2", 20)); result.put("userList", userEntitys);

前端

<span>3、迭代list</span> <div> <ul th:each="user,i : ${userList}"> <li th:text="${'序号'+(i['index']+1)+', 名字'+user.userName}"></li> </ul> </div>

image.png

4 date

java

result.put("NowDate", new Date());

html

<span>6、date</span> <div> <p>format : <span th:text="${#dates.format(NowDate)}"></span></p> <p>custom format : <span th:text="${#dates.format(NowDate,'yyyy-MM-dd HH:mm:ss')}"></span></p> <p>day : <span th:text="${#dates.day(NowDate)}"></span></p> <p>month : <span th:text="${#dates.month(NowDate)}"></span></p> <p>monthName : <span th:text="${#dates.monthName(NowDate)}"></span></p> <p>year : <span th:text="${#dates.year(NowDate)}"></span></p> <p>dayOfWeek : <span th:text="${#dates.dayOfWeek(NowDate)}"></span></p> <p>dayOfWeekName : <span th:text="${#dates.dayOfWeekName(NowDate)}"></span></p> <p>hour : <span th:text="${#dates.hour(NowDate)}"></span></p> <p>minute : <span th:text="${#dates.minute(NowDate)}"></span></p> <p>second : <span th:text="${#dates.second(NowDate)}"></span></p> <p>createNow : <span th:text="${#dates.createNow()}"></span></p> </div>

2.5.2 链接表达式 @{ }

使用此表达式,可以动态获取项目路径,改名等操作不影响。

修改配置文件项目路径

#修改项目名,链接表达式会自动修改路径,避免资源文件找不到 server: context-path=/emp

链接表达式

<div> <script th:src="@{/js/login.js}"></script> <script th:src="@{/js/login?k1=v1&k2=v2}"></script> </div>

2.5.4 内容渲染标签

1 th:text 文本渲染

仅渲染文本

<span>1、文本渲染</span> <p th:text="${user.userName}"></p>
2 dom渲染(代码常用)
<span>2、dom渲染</span> <p th:utext="'<button>按钮</button>'+${user.userName}"></p>

2.5.5 script获取变量值

<span>5、script获取变量值</span> <div> <script th:inline="javascript"> let userName = [[${user.userName}]]; alert(userName); </script> </div>

2.5.6 封装通用代码块 insert、replace、include

th:insert: 是在div中插入代码块。
th:replace: 代替当前div,与原html结构一致。
th:include: 直接引入代码,到当前。

路径:classpath:/templates/common

header.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <herder th:fragment="header"> <div> <h1>网页头部</h1> </div> </herder> </body> </html>

主页引用

index.html

<!-- 导入通用头部模板 --> <div th:include="common/header::header"></div>

参考:

  • 余胜军
  • https://freemarker.apache.org/docs/dgui_template_overallstructure.html
  • https://www.jianshu.com/p/5bbac20348ec

留言

专栏
文章
加入群聊