当前位置: 首页 > news >正文

FreeMarker模板引擎入门:从基础到实践的全面指南

前言

什么是FreeMarker

FreeMarker是一个基于模板生成文本输出的通用工具,它使用纯Java编写,能够生成HTML、XML、JSON、RTF、Java源代码等多种格式的文本。FreeMarker模板引擎允许将数据模型与模板文件结合,生成动态的文本输出,广泛应用于Web开发、邮件生成、报告生成等场景。以下是对FreeMarker使用的详细解析。

FreeMarker的基本概念

  • 模板文件(*.ftl):FreeMarker的模板文件通常以.ftl为后缀,其中包含了用于生成文本的标记和指令。
  • 数据模型:数据模型是一个包含要插入模板中数据的对象,通常是一个Map或JavaBean。
  • 输出:通过模板和数据模型的结合,FreeMarker生成最终的文本输出。

FreeMarker模板的基本组成部分

  • 文本:模板中直接输出的内容部分。
  • 注释:不会输出的内容,格式为<#-- 注释内容 -->
  • 取值(插值):代替输出数据模型的部分,格式为${数据模型}#{数据模型}
  • ftl指令:FreeMarker指令,类似于HTML标记,包括内建指令和自定义指令。

FreeMarker的基础语法

  • 字符输出

    • ${emp.name?if_exists}:变量存在时输出,否则不输出。
    • ${emp.name!}:变量存在时输出,否则输出空字符串。
    • ${emp.name?default("xxx")}:变量不存在时取默认值xxx。
    • 常用内部函数,如${"123<br>456"?html}对字符串进行HTML编码,${"str"?cap_first}使字符串第一个字母大写等。
  • 日期输出

    • ${emp.date?string('yyyy-MM-dd')}:格式化日期输出。
  • 数字输出

    • ${emp.name?string.number}:以数字形式输出。
    • ${emp.name?string.currency}:以货币形式输出。
    • ${emp.name?string.percent}:以百分比形式输出。
    • 数字格式化插值可采用#{expr;format}形式,其中格式可以是mX(小数部分最小X位)、MX(小数部分最大X位)等。
  • 声明变量

    • <#assign foo=false/>:声明变量,并插入布尔值进行显示。
    • ${foo?string("yes","no")}:当变量为真时输出“yes”,否则输出“no”。
  • 表达式中的运算符

    • 比较运算符:=或==(判断两个值是否相等)、!=(判断两个值是否不等)、>或gt(大于)、<或lt(小于)、>=或lte(大于等于)、<=或gte(小于等于)。
    • 算术运算符:+、-、*、/、%。
    • 逻辑运算符:&&(逻辑与)、||(逻辑或)、!(逻辑非)。

FreeMarker的控制语句

if逻辑判断

<#if condition>  ...  
<#elseif condition2>  ...  
<#elseif condition3>  ...  
<#else>  ...  
</#if>

switch语句

<#switch value>  <#case refValue1>  ...  <#break>  <#case refValue2>  ...  <#break>  <#case refValueN>  ...  <#break>  <#default>  ...  
</#switch>

 集合与循环

<#list empList as emp>  ${emp.name!}  
</#list>

或者通过索引遍历集合:

<#list 0..(empList!?size-1) as i>  ${empList[i].name!}  
</#list>

FreeMarker的高级功能

  1. 宏定义

    宏是一种可以在模板中定义并重复使用的代码块。通过宏定义,可以简化模板的编写,提高代码的可读性和可维护性。

  2. 自定义指令

    自定义指令是FreeMarker提供的一种扩展机制,允许用户根据自己的需求定义新的指令。自定义指令可以包含复杂的逻辑和操作,以满足特定的模板需求。

  3. 国际化与本地化

    FreeMarker支持国际化与本地化功能,允许根据用户的语言和地区设置生成不同语言的文本输出。这通常通过加载不同的语言资源文件来实现。

FreeMarker的使用步骤

  1. 导入FreeMarker库:将FreeMarker的jar包添加到项目中。
  2. 创建FreeMarker配置对象:使用Configuration类来创建FreeMarker的配置对象,并设置模板文件的路径、编码格式等。
  3. 获取模板文件:使用Configuration对象的getTemplate方法来获取模板文件的对象。
  4. 创建数据模型:创建一个数据模型对象,用于存储模板中所需的数据。
  5. 渲染模板:使用模板对象的process方法将数据模型与模板文件进行渲染,并将结果输出到指定的位置。

注意事项

  1. 模板文件的路径和文件名:确保模板文件的路径和文件名正确无误。
  2. 数据模型中的变量:确保在数据模型中定义了所有在模板中使用的变量。
  3. 表达式的语法和用法:检查表达式的语法和用法是否正确。
  4. 控制语句的语法和用法:检查控制语句的语法和用法是否正确。

FreeMarker基本使用案例

FreeMarker在我看来是用来代替JSP进行取值的一种方式,因为FreeMarker不需要再页面中书写额外配置和java代码就可以取到后台存储在各个作用域中的数据,代码十分类似HTML,接下来,我将演示如何使用FreeMarker进行取值等基本操作。

注意:接下来演示的项目是在整合了SSM框架的基础上进行的。

第一步:导入相关依赖

pom.xml

 <!--freemarker--><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.23</version></dependency>

第二步:添加FreeMarker配置到SpringMVC配置文件中

spring-mvc.xml

 <!-- 针对FREEMAKER的视图配置 --><bean id="viewResolver"class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"><property name="cache" value="true" /><property name="prefix" value="/ftl/" /><property name="suffix" value=".ftl" /><property name="contentType" value="text/html;charset=UTF-8"></property><property name="allowSessionOverride" value="true"/><property name="requestContextAttribute" value="request" /><property name="exposeSpringMacroHelpers" value="true" /><property name="exposeRequestAttributes" value="true" /><property name="exposeSessionAttributes" value="true" /></bean><bean id="freemarkerConfig"class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"><property name="templateLoaderPath" value="/" /><property name="freemarkerSettings"><props><prop key="template_update_delay">0</prop><prop key="default_encoding">UTF-8</prop><prop key="number_format">0.##########</prop><prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop><prop key="classic_compatible">true</prop><prop key="template_exception_handler">ignore</prop></props></property></bean>

使用FreeMarker视图解析器代替jsp视图解析器

第三步:创建Controller层控制器

FreeController

存储User对象的前提是我已经创建了User实体类

@Controller
public class FreeController {@RequestMapping("/free")public String freeTest(Model model){User user =new User();user.setUser_name("数码暴龙战士");user.setBirthday(new Date());model.addAttribute("user",user);List<User> list =new ArrayList<>();User u1 =new User();u1.setUser_name("独孤求败");User u2 =new User();u2.setUser_name("步惊云");User u3 =new User();u3.setUser_name("聂风");list.add(u1);list.add(u2);list.add(u3);model.addAttribute("list",list);return "free";}
}

 第四步:书写FreeMarker页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<#assign username="张三">
${username}
<hr/>
${user.user_name}
<hr/>
${user.password!"密码不存在"}
<hr/>
${user.birthday?string('yyyy-MM-dd HH:mm:ss zzzz')}
<hr/>
${user.birthday?date}
<hr/>
<#--判断对象属性值是否为空-->
<#if user.password?exists>有密码<#else >无数据
</#if>
<hr/>
<#--判断对象属性值是否为空-->
<#if user.password??>有密码
<#else >无数据
</#if>
<hr/><#include "/up.html"/>
<hr/>
<#assign arrList=['a','b','c','d']/>
<#if arrList?size=0>arrList数组为空<#else >数组不为空
</#if>
<hr/>
<br/><#list list as user>${user_index},${user.user_name}<br/>
</#list></body>
</html>

 代码分析

  • <#assign username="张三">   页面设置变量username,并赋值张三
    ${username}  页面取变量username的值
  • ${user.user_name}  获取controller中存储在request域中的user对象的user_name属性值
  • ${user.password!"密码不存在"}   因为password未存值,使用!判断,值是否为空,为空输出!后面的字符串
  • ${user.birthday?string('yyyy-MM-dd HH:mm:ss zzzz')} 使用?string(日期格式),进行Date类型的格式化显示,zzzz表示中国标准时间
  • ${user.birthday?date}  使用默认的格式解析日期(这里是年月日,不包括时分秒)
  • <#--判断对象属性值是否为空-->
    <#if user.password?exists>有密码<#else >无数据
    </#if>        注意<#else>的位置,写在<#if>标签中间
  • <#--判断对象属性值是否为空-->
    <#if user.password??>有密码
    <#else >无数据
    </#if>     两种判断方式,?exists等价于??
  • <#include "/up.html"/>   引入另一个html页面的内容,包括html,css和js
  • <#assign arrList=['a','b','c','d']/>
    <#if arrList?size=0>arrList数组为空<#else >数组不为空
    </#if>    定义数组/集合,根据集合或数组的长度进行判断
  • <#list list as user>${user_index},${user.user_name}<br/>
    </#list>    获取后台存入request域中的list集合,并变量输出;_index为固定写法,表示取索引下标,从0开始。
    

演示效果

相关文章:

FreeMarker模板引擎入门:从基础到实践的全面指南

前言 什么是FreeMarker FreeMarker是一个基于模板生成文本输出的通用工具&#xff0c;它使用纯Java编写&#xff0c;能够生成HTML、XML、JSON、RTF、Java源代码等多种格式的文本。FreeMarker模板引擎允许将数据模型与模板文件结合&#xff0c;生成动态的文本输出&#xff0c;广…...

YOLOv8模型改进 第十讲 添加全维度动态卷积(Omni-dimensional Dynamic Convolution,ODConv)

本篇文章将介绍一种全新的改进机制——全维度动态卷积ODConv&#xff0c;并展示其在YOLOv8中的实际应用。现全维动态卷积&#xff08;Omni-dimensional Dynamic Convolution&#xff0c;ODConv&#xff09;是一种先进的动态卷积设计&#xff0c;旨在通过引入多维注意力机制来提…...

【环境搭建】远程服务器搭建ElasticSearch

参考&#xff1a; 非常详细的阿里云服务器安装ElasticSearch过程..._阿里云服务器使用elasticsearch-CSDN博客 服务器平台&#xff1a;AutoDL 注意&#xff1a; 1、切换为非root用户&#xff0c;su 新用户名&#xff0c;否则ES无法启动 2、安装过程中没有出现设置账号密码…...

机器学习与神经网络:诺贝尔物理学奖的新篇章

机器学习与神经网络&#xff1a;诺贝尔物理学奖的新篇章 引言 近日&#xff0c;2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者&#xff0c;这是历史上的首次。诺贝尔物理学奖通常授予在自然现象和物理物质研究方面做出重大贡献的科学家。然而&#xff0c;今年…...

倍福TwinCAT程序中遇到的bug

文章目录 问题描述&#xff1a;TwinCAT嵌入式控制器CX5140在上电启动后&#xff0c;X001网口接网线通讯灯不亮&#xff0c;软件扫描不到硬件网口 解决方法&#xff1a;硬件断电重启后&#xff0c;X001网口恢复正常 问题描述&#xff1a;TwinCAT软件点击激活配置后&#xff0c;…...

R语言实现logistic回归曲线绘制

方式一&#xff1a;编制函数 x<-rnorm(10000)#设置随机种子 #编写绘图函数代码快 f <- function(x){y 1/(1 exp(-x))plot(x,y)}#sigmoid函数 f(x)​ 方式二&#xff1a;Sigmoid函数代码 x<-rnorm(10000)#设置随机种子 #编写绘图函数代码块 #y<-1/(1exp(-x)) y&…...

零宽字符(ZWSP)

前言 一个“所见非所得”的问题&#xff0c;示例如下&#xff1a; 查看原始DOM发现存在特殊字符&#xff1a; zero-width-space&#xff08;ZWSP&#xff09; 零宽空格是一种不可打印的Unicode字符&#xff0c;用于可能需要换行处。 在HTML中&#xff0c;零宽空格可以替代标…...

作业 定时发送邮件

[rootlocalhost zyc]# date -s 12:28 2024年 10月 15日 星期二 12:28:00 CST [rootlocalhost zyc]# vim /etc/chrony.conf [rootlocalhost zyc]# systemctl restart chronyd [rootlocalhost zyc]# date 2024年 10月 15日 星期二 12:36:00 CST [rootlocalhost zyc]# chronyc s…...

【排序】——2.快速排序法(含优化)

快速排序法 递归法 霍尔版本(左右指针法) 1.思路 1、选出一个key&#xff0c;一般是最左边或是最右边的。 2、定义一个begin和一个end&#xff0c;begin从左向右走&#xff0c;end从右向左走。&#xff08;需要注意的是&#xff1a;若选择最左边的数据作为key&#xff0c;则…...

AnaTraf | 网络分析系统:高效IT运维工具

目录 什么是网络分析系统&#xff1f; 网络分析系统的核心功能 二、网络分析系统在IT运维中的重要性 案例分析&#xff1a;如何快速应对网络拥塞 技巧分享&#xff1a;如何使用网络分析系统优化带宽 网络分析系统的部署与最佳实践 确定监控范围与关键设备 分析结果的可…...

踩坑日记:线上接口超时问题排查

1.背景: 上线后,功能测试. 进入小程序页面发现很慢,耗时超过5秒,打开skywalking发现大量接口耗时都很高. 2.top命令 服务器top命令查看cpu资源发现占用并不高 3.mysql查看sql运行情况 # 当前运行的所有事务 select * from information_schema.innodb_trx; 1 | …...

C语言中的段错误(Segmentation Fault):底层原理及解决方法

引言 在C语言编程中&#xff0c;“段错误”&#xff08;通常由操作系统信号 SIGSEGV 触发&#xff09;是一种常见的异常情况&#xff0c;它表明程序试图访问不受保护的内存区域。本文将深入探讨段错误的原因、底层原理、常见情况以及如何调试和解决这类错误。 段错误的定义 …...

1.两数之和 暴力枚举和暴力搜索法

1. 两数之和 已解答 简单 相关标签 相关企业 提示 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案&#xff0c;并且你不能使用两次相…...

你的收入达到了缴纳个人所得税的标准了吗?

在现代社会&#xff0c;个人所得税作为一种重要的税收形式&#xff0c;已经渗透到了我们每个人的日常生活中。它不仅关乎国家的财政收入&#xff0c;更与每个纳税人的切身利益息息相关。那么&#xff0c;你是否真正了解个人所得税的缴纳标准、计算方法以及相关的税收优惠政策呢…...

【C++贪心】2086. 喂食仓鼠的最小食物桶数|1622

本文涉及知识点 C贪心 LeetCode2086. 喂食仓鼠的最小食物桶数 给你一个下标从 0 开始的字符串 hamsters &#xff0c;其中 hamsters[i] 要么是&#xff1a; ‘H’ 表示有一个仓鼠在下标 i &#xff0c;或者’.’ 表示下标 i 是空的。 你将要在空的位置上添加一定数量的食物桶…...

notepad++中实现代码整体缩进和退格

我 | 在这里 ⭐ 全栈开发攻城狮、全网10W粉丝、2022博客之星后端领域Top1、专家博主。 &#x1f393;擅长 指导毕设 | 论文指导 | 系统开发 | 毕业答辩 | 系统讲解等。已指导60位同学顺利毕业 ✈️个人公众号&#xff1a;乡下小哥编程。回复 Java全套视频教程 或 前端全套视频教…...

如何调整配置请款单上的立账条件

顾问配置的立账条件取的是供应商档案里面的参数。与实际需求是不相匹配的。采购员商谈的立账条件经常是变化的。 措施&#xff1a;修改模板中立几账条件的OQL语句。 如下&#xff1a; select UFIDA::U9::AP::APBill::APBillHead.APBillLines.AccrueTerm.Name as 立账条件_名…...

骨传导耳机精选:2024最佳骨传导耳机有哪些?分享骨传导耳机top5

随着健康意识的普及&#xff0c;越来越多的人开始注重运动健身&#xff0c;并将音乐作为运动时的重要伴侣。然而&#xff0c;传统耳机在运动时易脱落且不易清洁的问题&#xff0c;给健身爱好者们带来了不少困扰。幸运的是&#xff0c;骨传导耳机的出现为这一问题提供了解决方案…...

for循环与webAPI练习题

爱太容易了&#xff0c;让爱维持才是最困难的部分 文章目录 for循环练习题webAPI练习题 for循环练习题 练习1&#xff1a;计算1-100的和 let sum 0for (let i 1; i < 100; i) {sum i}console.log(sum)练习2&#xff1a;将1-100之间所有是6的倍数的数字输出到控制台 for …...

FLUX | 轻松掌握FLUX.1 LoRA本地训练秘籍!

在数字艺术和创意领域&#xff0c;FLUX以其独特的虚实结合技术&#xff0c;已经成为艺术家和设计师们手中的利器。今天&#xff0c;我们激动地宣布&#xff0c;FLUX推出了一款全新的FLUX.1版本&#xff0c;它将LoRA本地训练技术完美融合&#xff0c;为用户提供了更加便捷和高效…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域&#xff1a;无处不在的数字助手 2、 计算机的进化史&#xff1a;从算盘到量子计算 3、计算机的分类&#xff1a;不止 “台式机和笔记本” 4、计算机的组件&#xff1a;硬件与软件的协同 4.1 硬件&#xff1a;五大核心部件 4.2 软件&#…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…...

【SpringBoot自动化部署】

SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一&#xff0c;能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时&#xff0c;需要添加Git仓库地址和凭证&#xff0c;设置构建触发器&#xff08;如GitHub…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合

作者&#xff1a;来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布&#xff0c;Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明&#xff0c;Elastic 作为 …...