[Java实战]Spring Boot 整合 Freemarker (十一)

[Java实战]Spring Boot 整合 Freemarker (十一)

引言

Apache FreeMarker 作为一款高性能的模板引擎,凭借其简洁语法卓越性能灵活扩展性,在 Java Web 开发中占据重要地位。结合 Spring Boot 的自动化配置能力,开发者能快速构建动态页面、生成报表或定制代码。本文将系统讲解整合流程、实战技巧、性能优化方案,并针对企业级场景提供深度解决方案。

一、Freemarker 核心优势与适用场景

1. 为什么选择 Freemarker?

特性说明
高性能编译型模板引擎,执行效率优于传统 JSP
语法简洁类似 Python 的直观语法,学习成本低
强类型支持严格的类型检查,减少运行时错误
多场景适用支持 HTML、XML、JSON、纯文本等多种输出格式

2. 与 Thymeleaf 对比

维度FreemarkerThymeleaf
模板类型非自然模板(需渲染后查看)自然模板(浏览器直接预览)
性能更高(适合高并发场景)中等
功能扩展支持自定义指令、宏依赖方言扩展
集成复杂度简单需额外配置布局方言

二、Spring Boot 整合 Freemarker 全流程

1. 环境准备

  • JDK 1.8+(推荐 LTS 版本)
  • Spring Boot 2.x(本文基于 2.1.8)
  • Maven/Gradle(本文使用 Maven)

2. 添加依赖

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

3. 基础配置(application.yml)

spring:freemarker:enabled: true                   # 启用 Freemarkertemplate-loader-path: classpath:/templates/  # 模板路径suffix: .ftl                    # 模板文件后缀charset: UTF-8                  # 编码格式cache: false                    # 开发环境关闭缓存settings:                       # Freemarker 全局配置classic_compatible: true      # 兼容旧版本语法number_format: 0.##           # 数字格式化datetime_format: yyyy-MM-dd HH:mm:ss

三、Freemarker 实战案例

案例 1:基础数据渲染

Controller
@Controller
public class ProductController {@GetMapping("/product")public String productDetail(Model model) {Product product = new Product("iPhone 15", 7999.00, 100);model.addAttribute("product", product);model.addAttribute("discount", 0.15);return "product";}
}
模板(product.ftl)
<!DOCTYPE html>
<html>
<head><title>商品详情</title>
</head>
<body><h1>${product.name}</h1><p>价格: ${product.price?string.currency}</p><p>库存: <#if product.stock &gt; 0><span style="color: green;">有货</span><#else><span style="color: red;">缺货</span></#if></p><p>折后价: ${(product.price * (1 - discount))?string.currency}</p>
</body>
</html>

在这里插入图片描述

案例 2:分页功能实现

分页工具类
public class Page<T> {private List<T> data;private int currentPage;private int totalPages;// Getter/Setter
}
分页模板(list.ftl)
<table><#list page.data as item><tr><td>${item.name}</td></tr></#list>
</table><div class="pagination"><#if page.currentPage &gt; 1><a href="/list?page=${page.currentPage - 1}">上一页</a></#if><span>${page.currentPage}/${page.totalPages}</span><#if page.currentPage < page.totalPages><a href="/list?page=${page.currentPage + 1}">下一页</a></#if>
</div>

四、高阶技巧与性能优化

1. 自定义指令(实现数据脱敏)

public class MaskDirective implements TemplateDirectiveModel {@Overridepublic void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) {String content = params.get("content").toString();int keepLength = Integer.parseInt(params.get("keep").toString());String masked = content.substring(0, keepLength) + "****";env.getOut().write(masked);}
}
注册指令
@Configuration
public class FreemarkerConfig {@Beanpublic FreeMarkerConfigurationFactoryBean getFreeMarkerConfiguration() {FreeMarkerConfigurationFactoryBean config = new FreeMarkerConfigurationFactoryBean();config.setTemplateLoaderPath("classpath:/templates");Map<String, Object> variables = new HashMap<>();variables.put("mask", new MaskDirective());config.setFreemarkerVariables(variables);return config;}
}
模板中使用
<p>手机号: <@mask content="13812345678" keep=3 /></p>

2. 性能优化策略

spring:freemarker:cache: true  # 生产环境开启缓存settings:template_update_delay: 3600  # 模板更新检查间隔(秒)localized_lookup: false      # 关闭本地化查找提升性能

3. 集成其他模板引擎(多引擎共存)

@Configuration
public class MultiTemplateConfig {@Beanpublic ViewResolver freeMarkerViewResolver() {FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();resolver.setPrefix("");resolver.setSuffix(".ftl");resolver.setOrder(1);  # 优先级高于 Thymeleafreturn resolver;}
}

五、常见问题与解决方案

1. 模板文件未找到(404)

  • 检查点
    • 文件是否位于 src/main/resources/templates
    • 模板名是否与 Controller 返回的视图名一致
    • 文件后缀是否为 .ftl

2. 变量解析失败

  • 错误示例Expression product.name is undefined
  • 解决
    • 确保 Controller 中通过 model.addAttribute() 添加变量
    • 检查变量名拼写(Freemarker 区分大小写)
    • 使用 ?? 判空:${product.name!''}

3. 静态资源加载问题

  • 正确引用方式
    <link href="/css/style.css" rel="stylesheet">
    <script src="/js/app.js"></script>
    
  • 确保路径配置:静态资源位于 src/main/resources/static

六、企业级应用扩展

1. 生成 PDF/Word 文档

利用 Freemarker 模板生成 HTML,再通过 Flying SaucerApache POI 转换为 PDF/Word:

Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
Template template = cfg.getTemplate("report.ftl");
String html = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
// 转换为 PDF
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(html);
renderer.layout();
renderer.createPDF(outputStream);

2. 集群环境模板热更新

结合 Spring Cloud Config 或 Nacos 实现模板动态加载:

@Scheduled(fixedRate = 60000)  # 每分钟检查更新
public void reloadTemplate() {configuration.clearTemplateCache();
}

七、总结

通过 Spring Boot 整合 Freemarker,开发者能够快速构建高效、灵活的动态页面系统。关键点包括:

  1. 快速整合:依赖配置与基础语法
  2. 高阶扩展:自定义指令与多引擎共存
  3. 性能优化:缓存策略与集群方案
  4. 企业级应用:文档生成与动态更新

扩展思考:如何结合 Freemarker 与前端框架(如 React)实现服务端渲染(SSR)?欢迎评论区交流!

附录

  • Freemarker 官方手册
  • Spring Boot 模板引擎配置指南

希望本教程对您有帮助,请点赞❤️收藏⭐关注支持!欢迎在评论区留言交流技术细节!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/80788.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DeepSeek:开启能源领域智能化变革新时代

目录 一、DeepSeek 与能源领域变革的邂逅1.1 DeepSeek 在人工智能领域的地位与特点1.2 能源行业面临的挑战与变革需求1.3 DeepSeek 在能源领域应用的重要性和意义 二、能源政策解读与科普新助手2.1 能源政策解读的深度变革2.2 能源科普的创新使者 三、能源项目可行性分析新利器…

uniapp设置 overflow:auto;右边不显示滚动条的问题

设置了overflow&#xff1a;auto;或者其它overflow的属性不显示滚动条是因为在uniapp中默认隐藏了滚动条 解决方法&#xff1a; //强制显示滚动条 ::-webkit-scrollbar {width: 8px !important;background: #ccc !important;display: block !important;}//设置滚动条颜色.cu-…

hyper-v安装ubuntu后时磁盘空间扩容

使用hyper-v创建虚拟机Ubuntu 22.04&#xff0c;直接使用的是磁盘镜像&#xff0c;原磁盘空间只有12GB&#xff0c;明显不够用呀&#xff0c;现在想要扩展到50GB&#xff0c;准备开始。 1、先关闭Ubuntu&#xff0c;再hyper-v管理器中调整磁盘容量到50GB 2、进入虚拟机 3、准备…

Prometheus 的介绍与部署(入门)

一、什么是Prometheus&#xff1b; 1.介绍 Prometheus 是一个功能强大的监控工具&#xff0c;适用于各种环境。通过简单的安装和配置&#xff0c;可以快速实现对系统和服务的监控。无论是单机环境、容器化环境还是 Kubernetes 集群&#xff0c;Prometheus 都能提供灵活…

Angular 知识框架

一、Angular 基础 1. Angular 简介 Angular 是什么&#xff1f; 基于 TypeScript 的前端框架&#xff08;Google 维护&#xff09;。 适用于构建单页应用&#xff08;SPA&#xff09;。 核心特性 组件化架构 双向数据绑定 依赖注入&#xff08;DI&#xff09; 模块化设计…

注解和 XML 两种方式有什么区别?

注解和 XML 是两种常见的配置方式&#xff08;尤其在 Java 开发中&#xff0c;如 Spring 框架&#xff09;&#xff0c;它们的主要区别体现在配置方式、代码耦合性、可读性、维护性等方面。以下是两者的对比&#xff1a; 1. 配置方式 注解&#xff08;Annotation&#xff09; 在…

Python爬虫实战:研究拦截器,实现逆向解密

1. 案例背景与研究目标 1.1 研究背景 在数字化时代,网络数据成为重要资源。许多网站通过加密技术保护数据传输,如电商平台的价格信息常以加密形式存在。爬虫技术与逆向工程的结合,为合法获取和分析此类数据提供了解决方案。 1.2 研究目标 开发完整的 Python 爬虫系统,实现…

Math工具类全面指南

Math工具类全面指南 前言一、Math 类的基础特性1.1 类的声明与常量1.2 数据类型支持 二、基础算术运算2.1 绝对值运算2.2 取整运算2.2.1 floor()&#xff1a;向下取整2.2.2 ceil()&#xff1a;向上取整2.2.3 round()&#xff1a;四舍五入取整 2.3 最大值与最小值 三、三角函数与…

嵌入式C语言中指针的不同类型及其特点分析

在 C 语言中,指针的类型主要可以分为以下几类: 1.1 基本类型指针 基本类型指针是指指向基础数据类型的指针,通常用于存储变量的地址。它们的类型与指向的变量类型相同。常见的基本类型指针包括: 整型指针:int *p,p是一个指向整型数据的指针。字符型指针:char *p,p是…

gd32e230c8t6 keil6工程模板

下载固件gd32e230c8t6固件官方下载&#xff08;需登录&#xff09; 或 蓝奏云 新建一个文件夹&#xff0c;把固件压缩包里的里的Firmware和Template拖进去 keil新建gd32e230c8工程 必须勾选CMSIS-CORE 新建一个文件夹&#xff0c;双击任意改名 点击manage project it…

SQL看最多的数据,但想从小到大排列看趋势

SQL 查询&#xff1a;从 test 表中获取本月的数据&#xff0c;并对数量最多的前10个流程按数量升序排序 假设表结构 test 表包含请求信息。workflow_base 包含流程的基本信息。 CREATE TABLE test (requestid INT, -- 请求IDworkflowid INT, -- 流程IDcurr…

WebGL知识框架

一、WebGL 基础概念 1. WebGL 简介 是什么&#xff1f; 基于 OpenGL ES 的浏览器 3D 图形 API&#xff0c;直接操作 GPU 渲染。 核心特点 底层、高性能、需手动控制渲染管线。 依赖 JavaScript 和 GLSL&#xff08;着色器语言&#xff09;。 与 Three.js 的关系 Three.js…

LabVIEW电涡流传感器自动校准系统

在工业生产中&#xff0c;尤其是大型旋转机械的运行监测环节&#xff0c;电涡流传感器的精准校准极为关键。传统手动校准方式存在诸多弊端&#xff0c;如人工参与度高、操作重复、效率低下等&#xff0c;难以满足现代工业快速发展的需求。基于 LabVIEW 开发的电涡流传感器自动校…

HCIP-BGP综合实验

一&#xff1a;拓扑图 二&#xff1a;需求分析 1&#xff0c;AS1存在两个环回&#xff0c;一个地址为192.168.1.0/24该地址不能在任何协议中宣告&#xff0c;AS3中存在俩个环回&#xff0c;一个地址为192.168.2.0/24该地址不能在任何协议中宣告&#xff0c;最终要求这两个环回…

嵌入式STM32学习——继电器

继电器模块引脚说明 VCC&#xff08;&#xff09;&#xff1a; 供电正极。连接此引脚到电源&#xff08;通常是直流电源&#xff09;&#xff0c;以提供继电器线圈所需的电流。 GND&#xff08;-&#xff09;&#xff1a; 地。连接此引脚到电源的负极或地。 IN&#xff08;或…

03_朴素贝叶斯分类

描述 朴素贝叶斯分类器与线性模型非常相似的一种分类器&#xff0c;但它的训练速度往往更快。这种高效率所付出的代价是&#xff0c;朴素贝叶斯模型的泛化能力要比线性分类器&#xff08;如LogisticRegression 和 LinearSVC&#xff09;稍差。 朴素贝叶斯模型高效的原因&…

Cabot:开源免费的 PagerDuty 替代品,让系统监控更简单高效

在当今复杂的IT环境中,及时发现并解决系统问题至关重要。而Cabot作为一款开源免费的监控工具,为开发和运维团队提供了强大而简单的解决方案。本文将详细介绍Cabot的核心功能、优势以及快速部署方法,帮助你更好地保障系统稳定性。 Cabot简介 Cabot是一个功能类似PagerDuty的开…

AI-02a5a5.神经网络-与学习相关的技巧-权重初始值

权重的初始值 在神经网络的学习中&#xff0c;权重的初始值特别重要。实际上&#xff0c;设定什么样的权重初始值&#xff0c;经常关系到神经网络的学习能否成功。 不要将权重初始值设为 0 权值衰减&#xff08;weight decay&#xff09;&#xff1a;抑制过拟合、提高泛化能…

TCP首部格式及三次握手四次挥手

TCP协议详解&#xff1a;首部格式与连接管理 一、TCP首部格式 TCP首部最小20字节&#xff0c;最大60字节&#xff0c;包含以下字段&#xff1a; | 源端口号(16bit) | 目的端口号(16bit) | | 序列号(32bit) | | 确认号(32bit) | | 数据偏移(4bit)| 保留(6bit) |U|A|P|R|S|…

Pytorch的Dataloader使用详解

PyTorch 的 DataLoader 是数据加载的核心组件&#xff0c;它能高效地批量加载数据并进行预处理。 Pytorch DataLoader基础概念 DataLoader基础概念 DataLoader是PyTorch基础概念 DataLoader是PyTorch中用于加载数据的工具&#xff0c;它可以&#xff1a;批量加载数据&#xf…