Freemarker模板引擎技术

问题】当渲染文章数据时,由于文章的数据很多,直接去查询文章内容表的话,效率比较低。
解决】使用freemarker将文章的内容通过模板技术生成静态的html文件存储到minio中,这样用户就只需要拿着minio的url去minio里获取静态页面即可。效率大大提高
在这里插入图片描述

模板引擎

Freemarker是一种模板引擎:一种基于模板和要改变的数据,并用来生成输出文本(html网页、电子邮件、配置文件、源代码…)的通用工具。不是面向最终用户的,而是一个Java类库。
在这里插入图片描述

步骤

  1. 导入依赖
<dependencies>
    <!-- freemarker -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-freemarker</artifactId>
    </dependency>
</dependencies>
  1. 添加application.yml配置
server:
  port: 8881 #服务端口
spring:
  application:
    name: freemarker-demo #指定服务名
  freemarker:
    cache: false  #关闭模板缓存,方便测试
    settings:
      template_update_delay: 0 #检查模板更新延迟时间,设置为0表示立即检查,如果时间大于0会有缓存不方便进行模板测试
    suffix: .ftl #指定Freemarker模板文件的后缀名(默认是.ftlh)

suffix的属性也可以是.html、.xml、.jsp等,但是一般是以ftl作为扩展名

  1. 在resources下创建templates,此目录为freemarker的默认模板存放目录。在templates下创建模板文件basic.ftl,模板中的插值表达式最终会被freemarker替换成具体的数据。
    basic.ftl文件
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Hello World!</title>
</head>
<body>
	<b>普通文本 String 展示:</b><br><br>
	Hello ${name} <br>
	<hr>
	<b>对象Student中的数据展示:</b><br/>
	姓名:${stu.name}<br/>
	年龄:${stu.age}
	<hr>
</body>
</html>
  1. 往模板里填数据,返回模板文件
@Controller // 因为要返回视图,而不是json字符串,所以这里不可以用@RestController
public class HelloController {
    @GetMapping("/basic")
    public String hello(Model model) {
        // name
        model.addAttribute("name", "xiaolin");
        // stu
        Student stu = new Student("03", 18);
        model.addAttribute("stu", stu);
        return "basic"; // 这里返回的数据必须和模板视图的名字一样,这样才能找到模板视图(别带后缀!!!)
    }
}

Freemarker指令语法

基础语法种类

1. 注释<#-- -->

介于其之间的内容会被Freemarker忽视

<#--我是一个freemarker注释-->

2. 插值表达式${...}

Freemarker会用真实的值替代${…}

Hello ${name}

3. FTL指令<#> </#>

名字前加#区分,Freemarker会解析标签中的表达式或逻辑。
例如:

<#list stus as stu>${stu.name}</#list> 

4. 文本

仅文本信息,不是freemarker的注释、插值、FTL指令的内容会被Freemarker忽略解析,直接输出内容。

<#--freemarker中的普通文本-->
我是一个普通的文本

集合指令(List、Map)

List

<table>
    <tr>
        <td>序号</td>
        <td>姓名</td>
        <td>年龄</td>
        <td>钱包</td>
    </tr>
    <#--遍历数据 stu指的是集合里的每一个数据-->
    <#list stus as stu>
        <tr>
            <#--获取当前集合的下标-->
            <td>${stu_index + 1}</td>
            <td>${stu.name}</td>
            <td>${stu.age}</td>
            <td>${stu.money}</td>
        </tr>
    </#list>
</table>

Map

获取map中某个key对应的值
  1. 通过map['keyname'].property
姓名:${stuMap['stu1'].name}<br/>
年龄:${stuMap['stu1'].age}<br/>
  1. 通过map.keyname.property
姓名:${stuMap.stu2.name}<br/>
年龄:${stuMap.stu2.age}<br/>
遍历map
<table>
    <tr>
        <td>序号</td>
        <td>姓名</td>
        <td>年龄</td>
        <td>钱包</td>
    </tr>
    <#--遍历数据 key指的是map中的每一个key-->
    <#list stuMap?keys as key>
        <tr>
            <#--获取当前集合的下标-->
            <td>${key_index + 1}</td>
            <td>${stuMap[key].name}</td>
            <td>${stuMap[key].age}</td>
            <td>${stuMap[key].money}</td>
        </tr>
    </#list>
</table>

if指令

<#if 表达式>
<#else>
</if>

【例】:姓名为小红的数据字体显示为红色

<#if name = '小红'>
	<span style = "color: red">${name}</span>
	<#else>
		<span>${name}</span>
</if>

在Freemarker中,=== 是一样的

运算符

数值运算符

  1. 加法:+
  2. 减法:-
  3. 乘法:*
  4. 除法:/
  5. 求余:%

比较运算符

在这里插入图片描述

= 和 != 可以用于字符串、数值、日期来比较是否相等
= 和 != 两边必须是相同类型的值,否则会产生错误
字符串"x"和"x "和"X"比较是不相等的
gt代替>,因为Freemarker会把>解析成FTL标签结束的字符串,可以用括号避免这种情况,如:<#if (x > y)>

逻辑运算符

  1. 逻辑与:&&
  2. 逻辑或:||
  3. 逻辑非:!

空值处理

  1. 判断某个变量是否存在使用:“??”
    用法:变量??
    • 变量存在,返回true
    • 不存在,返回false
<#if stus??>
	<#list stus as stu>
		...
	<#list>
</#if>
  1. 缺失的变量使用:!
    用法:!默认值
    • 使用!要指定一个默认值,当变量为空时显示默认值
    • 如果是嵌套对象,要使用()括起来
<#--如果name为空显示空字符串''-->
${name!''}
<#--如果stu或name为空,默认显示空字符串''-->
${(stu.name)!''}

内建函数

语法格式:变量 + ? + 函数名称

  1. 集合大小
${集合名?size}
  1. 日期格式化
    显示日期+时间:${today?datetime}
    自定义格式化:${today?string("yyyy年MM月")}
    显示时分秒:${today?time}
    显示年月日:${today?date}
  2. 内建函数c
    【场景】:point是数值类型,使用${point}会显示这个数字的数值,每三位使用逗号分隔。如果不想显示为每隔三位分割的数字,可以使用c函数将数字型转成字符串输出。
    在这里插入图片描述
model.addAttribute("poin", 123456780L);

使用内建函数c:

${point?c}
  1. 将json字符串转为对象
<#--assign标签的作用:定义一个变量-->
<#assign text="{'bank':'工商银行','account':'10101920201920212'}" />
<#--把json转成变量-->
<#assign data=text?eval />
开户行:${data.bank}
账号:${data.account}

注意:eval的使用可能不安全,如果传入的字符串内容不可控(比如来自用户输入),可能会导致安全问题(例如代码注入)

输出静态化文件

在这里插入图片描述

@SpringBootTest
public class FreemarkerTest {
    @Autowired
    private Configuration configuration;
    @Test
    public void test() throws IOException, TemplateException {
        Template template = configuration.getTemplate("test.ftl"); // 模板对象
        /**
         * 第一个参数:模型数据 mp
         * 第二个参数:输出流
         */
        Map<String, Object> mp = new HashMap<>();
        mp.put("name", "xiaolin");
        template.process(mp, new FileWriter("d:/list.html"));
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python在多个Excel文件中找出缺失数据行数多的文件

本文介绍基于Python语言&#xff0c;针对一个文件夹下大量的Excel表格文件&#xff0c;基于其中每一个文件内、某一列数据的特征&#xff0c;对其加以筛选&#xff0c;并将符合要求与不符合要求的文件分别复制到另外两个新的文件夹中的方法。 首先&#xff0c;我们来明确一下本…

Linux 内核中的 InfiniBand 核心模块:drivers/infiniband/core/device.c 分析

InfiniBand 是一种高性能、低延迟的网络互连技术,广泛应用于高性能计算(HPC)、数据中心和云计算等领域。Linux 内核中的 InfiniBand 子系统提供了对 InfiniBand 设备的支持,而 drivers/infiniband/core/device.c 文件则是 InfiniBand 核心模块的重要组成部分。本文将对 dev…

leetcode-不同路径问题

一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&#xff1f; 看见题目…

【网络协议】【http】【https】RSA+AES-TLS1.2

【网络协议】【http】【https】RSAAES-TLS1.2 https并不是一个协议 而是在传输层之间添加了SSL/TLS协议 TLS 协议用于应用层协议&#xff08;如 HTTP&#xff09;和传输层&#xff08;如 TCP&#xff09;之间&#xff0c;增加了一层安全性来解决 HTTP 存在的问题&#xff0c;H…

【16届蓝桥杯寒假刷题营】第1期DAY5

5.依依的询问最小值 - 蓝桥云课 问题描述 依依有个长度为 n 的序列 a&#xff0c;下标从 1 开始。 她有 m 次查询操作&#xff0c;每次她会查询下标区间在 [li​,ri​] 的 a 中元素和。她想知道你可以重新排序序列 a&#xff0c;使得这 m 次查询的总和最小。 求你求出 m 次…

Ext2 文件系统:数字世界的基石,深度解码超时空存储魔法

本篇博主将带大家深入底层探秘系统是如何与磁盘进行相互交流的&#xff0c;配合精美配图&#xff0c;细节讲解来带大家深入探究&#xff08;注&#xff1a;本篇文章建议了解磁盘内部物理结果组成及设计再进行阅读&#xff09;。 羑悻的小杀马特.-CSDN博客羑悻的小杀马特.擅长C…

Java面试专题——面向对象

面向过程和面向对象的区别 面向过程&#xff1a;当事件比较简单的时候&#xff0c;利用面向过程&#xff0c;注重的是事件的具体的步骤/过程&#xff0c;注重的是过程中的具体的行为&#xff0c;以函数为最小单位&#xff0c;考虑怎么做。 面向对象&#xff1a;注重找“参与者…

GeekHour

Linux Linux的是类Unix系统&#xff0c;作者是Linus&#xff0c;也是git的作者。符合GPL&#xff08;General Public License&#xff09;就可以Linux的使用、修改、再发布。 Linux四部分&#xff1a; 内核&#xff1a;驱动、内存管理、进程管理、文件系统、网络协议栈…。作…

学习golang语言时遇到的难点语法

作者是java选手&#xff0c;实习需要转go&#xff0c;记录学习go中遇到的一些与java不同的语法。 defer defer特性 1. 关键字 defer 用于注册延迟调用。 2. 这些调用直到 return 前才被执。因此&#xff0c;可以用来做资源清理。 3. 多个defer语句&#xff0c;按先进…

一个面向领域的直播平台开源!

面向教育等领域&#xff0c;二开后可以做视频会议等 在线直播平台 基于 Spring Boot 和 SRS 平台功能 视频直播 在线聊天 直播提醒 作业上传和批改 项目介绍了一个基于Spring Boot和SRS的在线直播平台&#xff0c;这个平台具备视频直播、在线聊天、直播提醒以及…

软件测试—— 接口测试(HTTP和HTTPS)

软件测试—— 接口测试&#xff08;HTTP和HTTPS&#xff09; HTTP请求方法GET特点使用场景URL结构URL组成部分URL编码总结 POST特点使用场景请求结构示例 请求标头和响应标头请求标头&#xff08;Request Headers&#xff09;示例请求标头 响应标头&#xff08;Response Header…

Mysql约束(学习自用)

一、概述 注意&#xff1a; 1&#xff09;多个约束之间用空格分开 二、外键约束 三、约束行为

linux-NFS网络共享存储服务配置

1.NFS服务原理 NFS会经常用到&#xff0c;用于在网络上共享存储&#xff0c;这样讲&#xff0c;你对NFS可能不太了解&#xff0c;举一个例子&#xff0c; 加入有三台机器A,B,C&#xff0c;它们需要访问同一个目录&#xff0c;目录中都是图片&#xff0c;传统的做法是把这些 图…

LabVIEW太赫兹二维扫描成像系统

使用LabVIEW设计太赫兹二维扫描成像系统。通过LabVIEW平台开发&#xff0c;结合硬件如太赫兹源、平移台、锁相放大器等&#xff0c;实现了高效、精准的成像功能。系统采用蛇形扫描方式&#xff0c;通过动态调整扫描参数&#xff0c;达到优化成像质量的目的。 ​ 项目背景 在非…

kafka学习笔记6 ACL权限 —— 筑梦之路

在Kafka中&#xff0c;ACL&#xff08;Access Control List&#xff09;是用来控制谁可以访问Kafka资源&#xff08;如主题、消费者组等&#xff09;的权限机制。ACL配置基于Kafka的kafka-acls.sh工具&#xff0c;能够管理对资源的读取、写入等操作权限。 ACL介绍 Kafka的ACL是…

ARM学习(42)CortexM3/M4 MPU配置

笔者之前学习过CortexR5的MPU配置,现在学习一下CortexM3/M4 MPU配置 1、背景介绍 笔者在工作中遇到NXP MPU在访问异常地址时,就会出现总线挂死,所以需要MPU抓住异常,就需要配置MPU。具体背景情况可以参考ARM学习(41)NXP MCU总线挂死,CPU could not be halted以及无法连…

Python----Python高级(正则表达式:语法规则,re库)

一、正则表达式 1.1、概念 正则表达式&#xff0c;又称规则表达式,&#xff08;Regular Expression&#xff0c;在代码中常简写为regex、 regexp或RE&#xff09;&#xff0c;是一种文本模式&#xff0c;包括普通字符&#xff08;例如&#xff0c;a 到 z 之间的字母&#xff0…

docker 使用远程镜像启动一个容器

使用前提&#xff1a; 首先你得安装docker,其次你得拥有一个远程镜像 docker run --name io_11281009 --rm -it -p 2233:22 -v .:/root/py -e ed25519_rootAAAAC3NzaC1lZDI1********Oy7zR7l7aUniR2rul ghcr.lizzie.fun/fj0r/io srv对上述命令解释&#xff1a; 1.docker run:…

SSM课设-学生管理系统

【课设者】SSM课设-学生管理系统 技术栈: 后端: SpringSpringMVCMybatisMySQLJSP 前端: HtmlCssJavaScriptEasyUIAjax 功能: 学生端: 登陆 学生信息管理 个人信息管理 老师端: 多了教师信息管理 管理员端: 多了班级信息管理 多了年级信息管理 多了系统用户管理

SpringMVC 实战指南:打造高效 Web 应用的秘籍

第一章&#xff1a;三层架构和MVC 三层架构&#xff1a; 开发服务器端&#xff0c;一般基于两种形式&#xff0c;一种 C/S 架构程序&#xff0c;一种 B/S 架构程序使用 Java 语言基本上都是开发 B/S 架构的程序&#xff0c;B/S 架构又分成了三层架构三层架构&#xff1a; 表现…