当前位置: 代码迷 >> 综合 >> Spring Boot 整合 FreeMaker
  详细解决方案

Spring Boot 整合 FreeMaker

热度:67   发布时间:2023-12-12 15:43:13.0

1. 使用Spring Initer快速构建SpringBoot工程,并选择需要的相关的依赖

 

 

 

2. FreeMarker 核心指令的练习

编写测试所用的实体类(Entity.Student)、Controller 类(Controller.freemarkerController) 以及 resources下的配置文件application.yml 还有在resources/templates目录下创建 test1.ftl

package com.example.freemarker.Entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.stereotype.Repository;import java.util.Date;
import java.util.List;/* 关于 Lombok 详细注解请参考 https://blog.csdn.net/qq_38179971/article/details/105037988  这篇文章 */
@Repository
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Student {private String name;private Integer age;private Date birthday;private Float money;private List<Student> friends;private Student bestFriend;}
package com.example.freemarkertest.Controller;import com.example.freemarkertest.Entity.Student;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import java.util.*;
import java.util.List;@Controller
public class freemarkerController {@RequestMapping("/test1")public String test1(Map<String,Object> map){/* 普通字符串 */map.put("name","杨超越");Student stu = new Student("stu",11,new Date(),1.11f,null,null);Student stu2 = new Student("stu2",22,new Date(),2.22f,null,null);Student stu3 = new Student("stu3",33,new Date(),3.33f,null,null);Student stu4 = new Student("stu4",44,new Date(),4.44f,null,null);/* List 集合 */List<Student> students = new ArrayList<>();stu.setFriends(students);stu2.setFriends(students);stu3.setFriends(students);stu4.setFriends(students);stu.setBestFriend(stu2);stu2.setBestFriend(stu3);stu3.setBestFriend(stu4);stu4.setBestFriend(stu);students.add(stu);students.add(stu2);students.add(stu3);students.add(stu4);map.put("students",students);/* HashMap 集合 */HashMap<String,Student> hashMap = new HashMap();hashMap.put("stu",stu);hashMap.put("stu2",stu2);hashMap.put("stu3",stu3);hashMap.put("stu4",stu4);map.put("hashMap",hashMap);/* 内建函数 之 日期转换 */Date today = new Date();map.put("today",today);/* 内建函数 之 内建函数C */map.put("number",1234567890);return "test1";}
}
# application.yml
server:port: 8080                    # 服务端口spring:application:name: freemarker-test       # 指定服务名freemarker:cache: false                #关闭模板缓存,方便测试settings:template_update_delay: 0  #检查模板更新延迟时间,设置为0表示立即检查,如果时间大于0会有缓存不方便进行模板测试suffix: .ftltemplate-loader-path: classpath:/templates/charset: UTF-8check-template-location: truecontent-type: text/htmlexpose-session-attributes: true     # 设定所有HttpSession的属性在merge到模板的时候,是否要都添加到model中.expose-request-attributes: true     # 设定所有request的属性在merge到模板的时候,是否要都添加到model中.request-context-attribute: request  # 指定RequestContext属性的名.
<!-- 在 resources/templates 目录下创建 test1.ftl -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>UserList</title>
</head>
<style>table tr td{border: 1px solid darkcyan}div {border-bottom: 1px solid mediumpurple;padding-bottom: 20px;}
</style>
<body><div><#-- 普通字符串 --><h5>模板中普通字符串的输出</h5>${name}的第一个FreeMaker模板页面
</div><div><#-- 模板中使用list指令遍历数据类型中的数据 --><h5>模板中使用list指令遍历数据类型中的数据</h5><table><tr><td>序号</td><td>姓名</td><td>年龄</td><td>钱包</td></tr><#-- 判断某变量是否存在使用 “??” 用法为:variable??,如果该变量存在,返回true,否则返回false --><#if students??><#list students as stu><tr><td>${stu_index +1}</td><td>${stu.name}</td><td>${stu.age}</td><td>${stu.money!'money为空'}</td></tr></#list></#if></table>
</div><#-- 模板中使用map指令遍历数据类型中的数据 -->
<div><h5>输出hashMap中单条数据的信息</h5>姓名:${hashMap.stu.name}<br/>年龄:${hashMap.stu.age}<br/>
</div>
<div><h5>遍历输出hashMap中所有数据的信息</h5><table><tr><td>序号</td><td>姓名</td><td>年龄</td><td>钱包</td></tr><#list hashMap?keys as k><tr><td>${k_index + 1}</td><td>${hashMap[k].name}</td><td>${hashMap[k].age}</td><td>${hashMap[k].money!'money为空'}</td></tr></#list></table>
</div>
<div><h5>模板中if指令的使用</h5><table><tr><td>序号</td><td>姓名</td><td>年龄</td><td>钱包</td></tr><#if students??><#list students as stu><tr><td>${stu_index +1}</td><td <#if stu.name == 'stu2'>style="background:green;"</#if>>${stu.name}</td><td>${stu.age}</td><td>${stu.money!'money为空'}</td></tr></#list></#if></table>
</div>
<div><h5>内建函数 之 集合大小</h5>${students?size}
</div>
<div><h5>内建函数 之 日期格式化</h5>显示年月日: ${today?date} <br/>显示时分秒: ${today?time} <br/>显示日期+时间: ${today?datetime} <br/>自定义格式化: ${today?string("yyyy年MM月dd日 HH时mm分ss秒")} <br/>
</div>
<div><h5>内建函数 之 内建函数C</h5>原样输出数字:${number}<br/>使用 内建函数C 将数字转换成字符后输出:${number?c}
</div>
<div><h5>使用内建函数assign 将JSON字符串转成对象</h5><#assign text="{'bank':'农业银行','account':'6228483169215254871'}" /><#assign data=text?eval />开户行:${data.bank} 账户:${data.account}
</div></body>
</html>

运行 FreemarkerTestApplication.java 启动类后 浏览器输入 localhost:8080/test1

3. 其他指令

3.1 运算符

3.1.1 算数运算符 FreeMarker表达式中完全支持算术运算,FreeMarker支持的算术运算符包括:+, - , * , / , %

3.1.2 逻辑 运算符 逻辑运算符有如下几个: 逻辑与:&& 逻辑或:|| 逻辑非:! 逻辑运算符只能作用于布尔值,否则将产生错误

3.1.3 比较运算符 表达式中支持的比较运算符有如下几个: 1 =或者==:判断两个值是否相等. 2 !=:判断两个值是否不等. 3 > 或者gt:判断左边值是否大于右边值

3.1.4 >=或者gte:判断左边值是否大于等于右边值

3.1.5 会有更好的效果,因为 FreeMarker会把>解释成FTL标签的结束字符,当然,也可以使用括 号来避免这种情况,如:y)>

3.2 空值处理

3.2.1 判断某变量是否存在使用 “??” 用法为:variable??,如果该变量存在,返回true,否则返回false 例:为防止stus为空报错可以加上判断如下:

<#if stus??>
<#list stus as stu>
......
</#list>
</#if>

3.2.2 缺失变量默认值使用 “!” 使用!要以指定一个默认值,当变量为空时显示默认值。 例: ${name!''}表示如果name为空显示空字符串。 如果是嵌套对象则建议使用()括起来。例如 ${(stu.bestFriend.name)!''} 的表示,如果stu或bestFriend或name为空默认显示空字符串。

4. 静态化生成HTML文件的俩种方式

如下图所示在test目录下建立 testFreemarkerGenerator.java 和 test2.ftl 俩个文件

└─test
    ├─java
    │      testFreemarkerGenerator.java
    │
    └─resources
        └─templates
                test2.ftl

/* "testFreemarkerGenerator.java" */import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Test;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;import java.io.*;
import java.util.HashMap;
import java.util.Map;public class testFreemarkerGenerator {/* 基于模板生成静态化文件夹 */@Testpublic void testGenerateHtml() throws IOException, TemplateException {/* 创建配置类 */Configuration configuration = new Configuration(Configuration.getVersion());/* 设置模板路径 */String classpath = this.getClass().getResource("/").getPath();configuration.setDirectoryForTemplateLoading(new File(classpath + "/templates/"));/* 设置字符集 */configuration.setDefaultEncoding("UTF-8");/* 加载模板 */Template template = configuration.getTemplate("test2.ftl");/* 数据模型 */Map<String,Object> map = new HashMap<>();map.put("name","杨超越");/* 静态化 */String content = FreeMarkerTemplateUtils.processTemplateIntoString(template,map);/* 静态化内容 */System.out.println(content);InputStream inputStream = IOUtils.toInputStream(content);/* 输出文件 */FileOutputStream fileOutputStream = new FileOutputStream(new File("D:/test21.html"));Integer copy = IOUtils.copy(inputStream,fileOutputStream);}/* 基于模板字符串生成静态化文件 */@Testpublic void testGeneratorHtmlByString() throws IOException, TemplateException {/* 创建配置类 */Configuration configuration = new Configuration(Configuration.getVersion());/* 模板的内容: 这里使用简单的字符串作为模板 */String templateString ="<html>\n" +"   <head></head>\n" +"   <body>\n" +"   这是${name}的第一个FreeMarker模板文件\n" +"   </body>\n" +"</html>";/* 模板加载器 */StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();stringTemplateLoader.putTemplate("template",templateString);configuration.setTemplateLoader(stringTemplateLoader);/* 得到模板 */Template template = configuration.getTemplate("template","utf-8");/* 数据模型 */Map<String,Object> map = new HashMap<>();map.put("name","欧阳娜娜");/* 静态化 */String content = FreeMarkerTemplateUtils.processTemplateIntoString(template,map);/* 静态化内容 */System.out.println(content);InputStream inputStream = IOUtils.toInputStream(content);/* 输出文件 */FileOutputStream fileOutputStream = new FileOutputStream(new File("D:/test22.html"));IOUtils.copy(inputStream,fileOutputStream);}
}
<!-- test2.ftl -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>UserList</title>
</head>
<style>table tr td{border: 1px solid darkcyan}div {border-bottom: 1px solid mediumpurple;padding-bottom: 20px;}
</style>
<body><div><#-- 普通字符串 --><h5>模板中普通字符串的输出</h5>${name}的第一个FreeMaker模板页面
</div></body>
</html>

4.1 使用模板文件静态化 定义模板文件,使用freemarker静态化程序生成html文件

运行 第一个测试方法 testGenerateHtml(),会发现 D盘下多出一个 test21.html 文件,打开该网页,与预期效果相符,测试成功。

4.2 使用模板字符串静态化 定义模板字符串,使用freemarker静态化程序生成html文件。

运行 第一个测试方法 testGenerateHtmlByString(),会发现 D盘下多出一个 test22.html 文件,打开该网页,与预期效果相符,测试成功。

  相关解决方案