深入解析Freemarker模板引擎及其在Spring Boot中的高级整合

目录

  • 引言
  • 1. Freemarker
    • 1.1.什么是Freemarker
    • 1.2 Freemarker模板组成部分
    • 1.3.优点
  • 2. Spring Boot整合Freemarker
    • 2.1 配置
    • 2.2 数据类型
  • 3. 案例
  • 总结

在这里插入图片描述

引言

Freemarker作为一款强大的模板引擎,与Spring Boot的整合能够极大地提升Web应用的开发效率和灵活性。本篇博客将深入探讨Freemarker的原理和核心概念,并重点介绍在Spring Boot项目中如何配置和应用Freemarker模板引擎。通过全面讲解与丰富示例,旨在帮助读者充分理解并熟练运用这一强大的技术组合。

1. Freemarker

1.1.什么是Freemarker

FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

模板编写为FreeMarker Template Language (FTL)。它是简单的,专用的语言, 不是 像PHP那样成熟的编程语言。 那就意味着要准备数据在真实编程语言中来显示,比如数据库查询和业务运算, 之后模板显示已经准备好的数据。在模板中,你可以专注于如何展现数据, 而在模板之外可以专注于要展示什么数据。

在这里插入图片描述

这种方式通常被称为MVC (模型 视图 控制器) 模式,对于动态网页来说,是一种特别流行的模式。 它帮助从开发人员(Java 程序员)中分离出网页设计师(HTML设计师)。设计师无需面对模板中的复杂逻辑, 在没有程序员来修改或重新编译代码时,也可以修改页面的样式。

而FreeMarker最初的设计,是被用来在MVC模式的Web开发框架中生成HTML页面的,它没有被绑定到 Servlet或HTML或任意Web相关的东西上。它也可以用于非Web应用环境中。

1.2 Freemarker模板组成部分

FreeMarker模板文件主要由如下4个部分组成:

  • 文本:直接输出的部分
  • 注释:使用<#-- … -->格式做注释,里面内容不会输出
  • 插值:即${…}或#{…}格式的部分,类似于占位符,将使用数据模型中的部分替代输出
  • FTL指令:即FreeMarker指令,全称是:FreeMarker Template Language,和HTML标记类似,但名字前加#予以区分,不会输出

FreeMarker与Web容器无关

FreeMarker与Web容器无关,即在Web运行时,它并不知道Servlet或HTTP,故此FreeMarker不仅可以用作表现层的实现技术,而且还可以用于生成XML,JSP或Java等各种文本文件。

在Java Web领域,FreeMarker是应用广泛的模板引擎,主要用于MVC中的view层,生成html展示数据给客户端,可以完全替代JSP。

总之,FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写,模板中没有业务逻辑,外部Java程序通过数据库操作等生成数据传入模板(template)中,然后输出页面。它能够生成各种文本:HTML、XML、RTF、Java源代码等等,而且不需要Servlet环境,并且可以从任何源载入模板,如本地文件、数据库等等。

1.3.优点

FreeMarker的诞生是为了取代JSP。虽然JSP功能强大,可以写Java代码实现复杂的逻辑处理,但是页面会有大量业务逻辑,不利于维护和阅读,更不利于前后台分工,容易破坏MVC结构,所以舍弃JSP,选择使用FreeMarker是大势所趋。当前很多企业使用FreeMarker取代JSP,FreeMarker有众多的优点,如下所示:

  • 很好地分离表现层和业务逻辑

JSP功能很强大,它可以在前台编写业务逻辑代码,但这也带来了一个很大的弊端——页面内容杂乱,可读性差,这将会大大增加后期的维护难度。而FreeMarker职责明确,功能专注,仅仅负责页面的展示,从而去掉了繁琐的逻辑代码。FreeMarker的原理就是:模板+数据模型=输出,模板只负责数据在页面中的表现,不涉及任何的逻辑代码,而所有的逻辑都是由数据模型来处理的。用户最终看到的输出是模板和数据模型合并后创建的。

  • 提高开发效率

众所周知,JSP在第一次执行的时候需要转换成Servlet类,之后的每次修改都要编译和转换。这样就造成了每次修改都需要等待编译的时间,效率低下。而FreeMarker模板技术并不存在编译和转换的问题,所以就不会存在上述问题。相比而言,使用FreeMarker可以提高一定的开发效率。

  • 明确分工

JSP页面前后端的代码写到了一起,耦合度很高,前端开发需要熟悉后台环境,需要去调试,而后台开发人员需要去做不熟悉的前端界面设计。对两者而言,交替性的工作需要花费一定的学习成本,效率低下。而使用FreeMarker后,前后端完全分离,大家各干各的,互不影响。

  • 简单易用,功能强大

FreeMarker支持JSP标签,宏定义比JSP Tag方便,同时内置了大量常用功能,比如html过滤,日期金额格式化等等。FreeMarker代码十分简洁,上手快,使用非常方便。

2. Spring Boot整合Freemarker

首先先把springboot项目启动配置好

2.1 配置

配置pom.xml

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

配置yml

      freemarker:# 设置模板后缀名suffix: .ftl# 设置文档类型content-type: text/html# 设置页面编码格式charset: UTF-8# 设置页面缓存cache: false# 设置ftl文件路径template-loader-path: classpath:/templates# 设置静态文件路径,js,css等mvc:static-path-pattern: /static/**

然后在resource创建templates包,在templates包里面创建index.flt

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
${name}
</body>
</html>

PageController

package com.yuan.springboot2.Controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;/*** @author 叶秋* @site* @company 卓京公司* @create 2023-12-13 19:17*/
@Controller
public class PageController {@RequestMapping("/")public String home(Model model){model.addAttribute("name","zs");return "index";}@RequestMapping("/{path}")public String to(@PathVariable("path") String path){return path;}@RequestMapping("/{dir}/{path}")public String to(@PathVariable("dir") String dir,@PathVariable("path") String path){return dir+"/"+path;}
}

在这里插入图片描述

2.2 数据类型

在文本中确定字符串值的方法是看双引号,比如: "some text",或单引号,比如: 'some text'。这两种形式是等同的。 如果文本自身包含用于字符引用的引号 ( "')或反斜杠时, 应该在它们的前面再加一个反斜杠;这就是转义。 转义允许直接在文本中输入任何字符, 也包括换行。

${"It's \"quoted\" and
this is a backslash: \\"}

字符串类型处理:

方法含义
?substring(start,end)截取字符串(左闭右开)
?uncap_first首字母小写输出
?cap_first首字母大写输出
?lower_case字母转小写输出
?upper_case字母转大写输出
?length获取字符串长度
?starts_with(“xx”)?string是否以指定字符开头(boolean类型)
?ends_with(“xx”)?string是否以指定字符结尾(boolean类型)
?index_of(“xx”)获取指定字符的索引
?trim去除字符串前后空格
?replace(“xx”,“xx”)替换指定字符串

字符串空值情况处理:

FreeMarker 的变量必须赋值,否则就会抛出异常。而对于 FreeMarker 来说,null 值和不存在的变量是完全一样的,因为 FreeMarker 无法理解 null 值。

<#-- 如果值不存在,直接输出会报错 -->
<#--${str}-->
<#-- 使用!,当值不存在时,默认显示空字符串 -->
${str!}<br>
<#-- 使用!"xx",当值不存在时,默认显示指定字符串 -->
${str!"这是一个默认值"}<br>
<#-- 使用??,判断字符串是否为空;返回布尔类型。如果想要输出,需要将布尔类型转换成字符串 -->
${(str??)?string}<br>

3. 案例

pageController

package com.yuan.springboot2.Controller;import com.yuan.springboot2.mapper.TBookMapper;
import com.yuan.springboot2.pojo.TBook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;import java.util.List;/*** @author 叶秋* @site* @company 卓京公司* @create 2023-12-13 19:17*/
@Controller
public class PageController {@Autowiredprivate TBookMapper tBookMapper;@RequestMapping("/")public String home(Model model){List<TBook> tBooks = tBookMapper.selectAllbook();model.addAttribute("name","zs");model.addAttribute("tBooks",tBooks);return "index";}@RequestMapping("/{path}")public String to(@PathVariable("path") String path){return path;}@RequestMapping("/{dir}/{path}")public String to(@PathVariable("dir") String dir,@PathVariable("path") String path){return dir+"/"+path;}@RequestMapping("/del")public String del(TBook tBook){tBookMapper.deleteByPrimaryKey(Long.valueOf(tBook.getId()));return "redirect:/";}@RequestMapping("/add1")public String add1(TBook tBook){return "add1";}@RequestMapping("/edit")public String edit(TBook tBook){if(tBook.getId()==null){tBookMapper.insertSelective(tBook);}else{tBookMapper.updateByPrimaryKeySelective(tBook);}return "redirect:/";}@RequestMapping("/chaxun")public String chaxun(TBook tBook,Model model){if(tBook.getId()!=null){TBook tBook1 = tBookMapper.selectByPrimaryKey(Long.valueOf(tBook.getId()));model.addAttribute("tBook1",tBook1);}model.addAttribute("tBook1",tBook);return "add";}}

add

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><#include "common.ftl">
</head>
<body><form action="${ctx}/edit?id=${tBook1.id}" method="post"><div class="form-group" ><label for="itemName">书籍名称</label><input type="text" class="form-control" name="bookname" id="bookname" value="${tBook1.bookname}" placeholder=""></div><div class="form-group"><label for="itemName">书籍价格</label><input type="text" class="form-control" name="price" id="price" value="${tBook1.price}" placeholder=""></div><div class="form-group"><label for="itemName">书籍类型</label><input type="text" class="form-control" name="booktype" id="booktype" value="${tBook1.booktype}" placeholder=""></div><button type="submit" class="btn btn-primary">确定</button></form><script></script>
</body>
</html>

index

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>Title</title><#include "common.ftl">
</head>
<body>
${name}<a href="${ctx}/a"></a>
<a href="${ctx}/add1">新增</a>
<#if tBooks??><table class="table table-striped"><#list tBooks as b><tr><td>${b.id}</td><td>${b.bookname} </td><td>${b.price}</td><td>${b.booktype}</td><td><a href="${ctx}/del?id=${b.id}">删除</a></td><td><a href="${ctx}/chaxun?id=${b.id}">修改</a></td></tr></#list></table><div class="container mt-5"></div></#if>
</body>
</html>

common

<#assign ctx="${springMacroRequestContext.contextPath}">
<link rel="stylesheet" href="${ctx}/bootstrap-3.4.1-dist/css/bootstrap.css">
<script src="${ctx}/jquery-3.6.1.js">
<script src="${ctx}/bootstrap-3.4.1-dist/js/bootstrap.js"></script>

总结

总结部分将对本篇博客进行回顾,并强调Freemarker模板引擎在Spring Boot中的重要性和应用前景。通过深入的讲解和丰富的实例,本篇博客旨在帮助读者掌握Freemarker模板引擎的核心概念和应用技巧,并能够灵活应用于实际的Web开发项目中。

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

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

相关文章

探索 Vim:一个强大的文本编辑器

引言&#xff1a; Vim&#xff08;Vi IMproved&#xff09;是一款备受推崇的文本编辑器&#xff0c;拥有强大的功能和高度可定制性&#xff0c;提供丰富的编辑和编程体验。本文将探讨 Vim 的基本概念、使用技巧以及为用户带来的独特优势。 简介和发展 1. Vim 的简介和历史 V…

发布jar包到maven中央仓库

1. 环境 在网上找的很多文章中写得都有很多问题&#xff0c;这里记录一下最近一次成功地发布jar包到maven中央仓库的过程。并附带上每一个步骤官方的指导链接。 系统&#xff1a;mac&#xff08;windows系统在下载辅助工具时不太一样&#xff0c;在配置上和mac系统没有区别&…

docker部署go gin框架 Linux环境

目录 文章目的是什么 环境介绍 Linux 环境下 docker 部署 go gin 详细步骤 部署 gin 文章目的是什么 假设我们学习了 go 语言&#xff0c;在 Linux 上安装了 go 相关的程序&#xff0c;也能直接运行&#xff0c;使用以下命令&#xff1a; go run main.go 假如代码是这样的…

算法中的最优化方法课程复习

算法中的最优化方法课程复习 单模函数、拟凸函数、凸函数证明证明一个线性函数与一个凸函数的和也是凸的 梯度线性规划标准形式以及如何标准化标准形式常见标准化方法线性化技巧 单纯形法二次规划无约束优化Nelder-Mead线搜索FR共轭梯度法例题 优化算法的选择、停止准则算法选择…

electron命令下载失败,手动安装教程

现象&#xff1a;pnpm i electron, 一直卡在提示错误node install.js 一 、下载需要的electron版本 地址 二、下载完毕&#xff0c;解压压缩包&#xff0c; 进入项目的node_modules/electron文件夹&#xff0c;创建dist文件夹&#xff0c;将下载的zip包里的文件复制到dist…

链路追踪详解(四):分布式链路追踪的事实标准 OpenTelemetry 概述

目录 OpenTelemetry 是什么&#xff1f; OpenTelemetry 的起源和目标 OpenTelemetry 主要特点和功能 OpenTelemetry 的核心组件 OpenTelemetry 的工作原理 OpenTelemetry 的特点 OpenTelemetry 的应用场景 小结 OpenTelemetry 是什么&#xff1f; OpenTelemetry 是一个…

DevEco Studio 鸿蒙(HarmonyOS)项目结构

DevEco Studio 鸿蒙&#xff08;HarmonyOS&#xff09;项目结构 一、操作环境 操作系统: Windows 10 专业版 IDE:DevEco Studio 3.1 SDK:HarmonyOS 3.1 二、项目结构 创建简单的Hello World移动应用项目结构如下图 由上到下说明各个文件夹的作用 .hvigor&#xff1a;存…

阅读笔记——《UTOPIA: Automatic Generation of Fuzz Driverusing Unit Tests》

【参考文献】Jeong B, Jang J, Yi H, et al. UTOPIA: automatic generation of fuzz driver using unit tests[C]//2023 IEEE Symposium on Security and Privacy (SP). IEEE, 2023: 2676-2692.【注】本文仅为作者个人学习笔记&#xff0c;如有冒犯&#xff0c;请联系作者删除。…

智慧储能数字孪生:能源未来的智慧引擎

随着社会对清洁能源的需求不断增加&#xff0c;智能储能技术成为能源转型的关键驱动力。在这一领域中&#xff0c;数字孪生技术的应用为智慧储能带来了全新的可能性。数字孪生是指数字化、实时、可视化的模拟系统&#xff0c;通过复制现实世界中的对象或过程&#xff0c;为智能…

SpeechGPT领航:创新的130亿参数跨模态AI模型

引言 在人工智能的最新进展中&#xff0c;SpeechGPT以其130亿参数的规模和跨模态会话能力引起了业界的广泛关注。这一由复旦大学邱锡鹏教授团队开发的模型&#xff0c;不仅在技术层面上取得了重大突破&#xff0c;也为多模态人工智能&#xff08;AI&#xff09;的未来发展指明…

Selenium库自动化测试入门

前言 为什么要学selenium&#xff1f;&#xff1f;前面已经学了requests库我们会发现 对于绝大多数动态渲染的网页来说&#xff0c;用requests进行爬虫比较繁琐。 所以我们还是要学习一下selenium库&#xff0c;以帮助我们更高效的爬取网页。 环境&#xff1a; pychar 202…

机器学习算法新手入门指南

AI算法的种类在人工智能领域中非常丰富&#xff0c;而且多样化&#xff0c;AI算法利用数学、统计学和计算机科学等领域的原理和方法&#xff0c;通过模拟人类智能和学习能力来解决各种复杂的问题。 在监督学习领域&#xff0c;我们有经典的线性回归和逻辑回归算法&#xff0c;…

光栅化渲染:可见性问题和深度缓冲区算法

在前面第二章中&#xff0c;我们了解到&#xff0c;在投影点&#xff08;屏幕空间中的点&#xff09;的第三个坐标中&#xff0c;我们存储原始顶点 z 坐标&#xff08;相机空间中点的 z 坐标&#xff09;&#xff1a; 当一个像素与多个三角形重叠时&#xff0c;查找三角形表面上…

Java 多线程之线程安全集合

文章目录 一、概述二、List 接口线程安全实现类2.1 普通 List 变线程安全 List2.2 Vector2.3 CopyOnWriteArrayList 三、Map 接口线程安全实现类3.1 普通 Map 变线程安全 Map3.2 Hashtable3.3 ConcurrentHashMap3.4 ConcurrentSkipListMap 有序/跳表 四、Set 接口线程安全实现类…

J2EE(架构师考试复习资料)

J2EE 是针对 Web Service、业务对象、数据访问和消息报传送的一组规范。这组应用编程接口确定了 Web 应用与驻留它们的服务器之间的通信方式。J2EE 注重两件事&#xff0c;一是建立标准&#xff0c;使 Web 应用的部署与服务器无关&#xff1b;二是使服务器能控制构件的生命周期…

自定义Mybatis LanguageDriver性能优化

场景&#xff1a;高并发情况下mybatis 动态sql 解析 锁问题优化 优化前 并发测试 XMLLanguageDriver 类 的 createSqlSource 方法有锁 而且 每次执行时都会走该方法 优化前 &#xff1a; 线程有Block 优化后的 LanguageDriver public class CustomXMLLanguageDriver im…

大数据机器学习与深度学习——回归模型评估

大数据机器学习与深度学习——回归模型评估 回归模型的性能的评价指标主要有&#xff1a;MAE(平均绝对误差)、MSE(平均平方误差)、RMSE(平方根误差)、R2_score。但是当量纲不同时&#xff0c;RMSE、MAE、MSE难以衡量模型效果好坏&#xff0c;这就需要用到R2_score。 平均绝对…

Python实现多种图像锐化方法:拉普拉斯算子和Sobel算子

Python实现多种图像锐化方法&#xff1a;拉普拉斯算子和Sobel算子 图像和视频逐渐成为人们生活中信息获取的重要来源&#xff0c;而图像和视频在传输过程中有很多因素可能造成图像模糊&#xff0c;比如不正确的聚焦会产生离焦模糊&#xff0c;景物和照相机的相对运动会造成运动…

GBASE南大通用携手宇信科技打造“一表通”全链路解决方案

什么是“一表通”&#xff1f; “一表通”是国家金融监督管理总局为发挥统计监督效能、完善银行保险监管统计制度、推进监管数据标准化建设、打破数据壁垒&#xff0c;而制定的新型监管数据统计规范。相较于以往的报送接口&#xff0c;“一表通”提高了对报送时效性、校验准确性…

java集合的迭代器与遍历

文章目录 迭代器Iterator1、什么是Iterator2&#xff0c;iterator接口的API3、Irerator()方法细节解释4. Irerator的原理示意图5. forEach循环与Iterator遍历的区别与联系 ListIterator1.ListIterator的概述(1) 概念(2) 解析 2.ListIterator的生成3.ListIterator的API4.ListIte…