【Spring Boot】视图渲染技术之Freemarker

一、引言

1、什么是Freemarker

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

        FreeMarker是免费的,基于Apache许可证2.0版本发布。其模板编写为FreeMarker Template Language(FTL),属于简单、专用的语言。它帮助从开发人员(Java 程序员)中分离出网页设计师(HTML设计师)。

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

2、Freemarker模板组成部分

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

  1. 文本:直接输出的部分

  2. 注释:使用<#-- ... -->格式做注释,里面内容不会输出

  3. 插值:即${...}或#{...}格式的部分,类似于占位符,将使用数据模型中的部分替代输出

  4. FTL指令:即FreeMarker指令,全称是:FreeMarker Template Language,和HTML标记类似,但名字前加#予以区分,不会输出

3、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环境,并且可以从任何源载入模板,如本地文件、数据库等等。

4、优缺点

①优点

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代码十分简洁,上手快,使用非常方便。

综合以上得到以下:

  1. 彻底的分离表现层和业务逻辑,使得页面内容更加清晰,后期修改和维护更加方便。
  2. 提高开发效率,因为FreeMarker模板技术不存在编译和转换的问题。
  3. 使得开发过程中的人员分工更加明确,程序员和界面设计人员可以更好地协作。

③缺点

  1. 无法在模板中使用Java代码,这可能会限制一些复杂逻辑的实现。
  2. 相对于JSP来说,FreeMarker的模板语法较为简单,可能无法满足一些复杂的页面需求。

二、Freemarker常见指令

1、处理不存在的值

  • 不存在值检测操作符

使用形式: unsafe_expr??(unsafe_expr)??

这个操作符告诉我们一个值是否存在。基于这种情况, 结果是 truefalse

<#if name??>存在
<#else>不存在
</#if>
  • exists用在逻辑判断

exists用作逻辑判断,返回的是true或者false。

<#if name?exists>${name}
</#if>
  • if_exists用来打印东西

if_exists用于输出的时候,如果存在则输出,不存在就输出空字符串

${name?if_exists}

2、assign

使用该指令你可以创建一个新的变量, 或者替换一个已经存在的变量。语法格式如下:

<#assign name1=value1 name2=value2 ... nameN=valueN>
或
<#assign name>hello
</#assign>

案例演示:

<#-- 创建一个str的变量 -->
<#assign str="hello">
<#-- 输出str -->
${str} <br>
<#-- 一次创建多个变量 -->
<#assign num=1 names=["zs","ls","ww"] >
${num} -- ${names?join(",")}

3、if/elseif/else

你可以使用 ifelseifelse 指令来条件判断是否越过模板的一个部分。 *condition* 必须计算成布尔值, 否则错误将会中止模板处理。elseifelse 必须出现在 if 内部 (也就是,在 if 的开始标签和结束标签之间)。 if 中可以包含任意数量的 elseif(包括0个) 而且结束时 else 是可选的。

<#if 条件1>...
<#elseif 条件2>...
<#elseif 条件3>...
...
<#else>...
</#if>

4、list

list 指令执行在 list 开始标签和 list 结束标签 ( list 中间的部分) 之间的代码, 对于在序列(或集合)中每个值指定为它的第一个参数。 对于每次迭代,循环变量将会存储当前项的值。

循环变量仅仅存在于 list 标签体内。 而且从循环中调用的宏/函数不会看到它(就像它只是局部变量一样)。

<#list s as item>${s.name}
<#else>暂无
</#list>

list 中的 else 仅从 FreeMarker 2.3.23 版本开始支持。

注意:

  • else 部分是可选的, 而且仅仅从 FreeMarker 2.3.23 版本开始支持。

  • sequence: 将我们想要迭代的项,算作是序列或集合的表达式

  • item: 循环变量的名称 (不是表达式)

<#list arrs as item>${item}
<#else>集合是空的
</#list>

5、include

可以使用它在你的模板中插入另外一个 FreeMarker 模板文件 (由 path 参数指定)

<#include path>
或
<#include path options>

这里:

  • path: 要包含文件的路径;

  • options: 一个或多个这样的选项: encoding=encoding, parse=parse

    • encoding: 算作是字符串的表达式

    • parse: 算作是布尔值的表达式(为了向下兼容,也接受一部分字符串值)

    • ignore_missing: 算作是布尔值的表达式

<h1>Hello Freemarker</h1>
<#include "/common/head.ftl">

三、SpringBoot整合Freemarker

1、配置

引入依赖pom.xml

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

添加application.ymlapplication.properties文件配置

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

2、新建模板

这里Freemarker选项需要到settings(设置) -> Editor(编辑器) -> File And Code Templates(文件和代码模板)中进行配置。扩展最好还是用ftl

最后,请选择resources/templates目录,右键 New -> Freemarker 新建模板文件(.ftl)。

创建FreemarkerController,并配置跳转页面路径:

@Controller
public class FreemarkerController {@RequestMapping("/")public String index() {return "index";}
}

四、综合案例

新建一个common.ftl文件引入我们的资源.比如我们的jQuery的资源

<#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>
<script src="${ctx}/bootstrap-3.4.1-dist/js/bootstrap.js"></script>

index.ftl里面进行页面的编写。

<!doctype html>
<html lang="zh">
<head><title>index</title><style>td {padding: 20px;text-align: center;}</style><#include "common.ftl">
</head>
<body>
<a href="${ctx}/save">增加</a>
<#if Books??><table class="table table-striped"><#list Books as book><tr><td>${book.id}</td><td>${book.bookname}</td><td>${book.price}</td><td>${book.booktype}</td><td><a href="${ctx}/del?id=${book.id}">删除</a><a href="${ctx}/saveEdit?id=${book.id}">修改</a></td></tr></#list></table>
</#if>
</body>
</html>

在这之前我们调用好我们的方法并且能实现,最好我们调用Controller层。

import com.example.springboot01.entity.TBook;
import com.example.springboot01.service.TBookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;import java.util.List;@Controller
public class FreemarkerController {@Autowiredprivate TBookService tBookService;@RequestMapping("/")public String index(Model model) {List<TBook> tBooks = tBookService.selectAll();model.addAttribute("Books", tBooks);return "index";}

运行我们的spring boot访问看结果。

save.ftl文件代码

<#--初始化-->
<#--${book = null}-->
<#--${edit = false}--><#--检查是否选择/存在了-->
<#--<#if book??>-->
<#--    ${edit = true}-->
<#--    ${book = books[bookId]}-->
<#--</#if>--><html>
<head><title>Books</title>
</head>
<body>
<#--<h1>Books</h1>-->
<#if book??><h1>修改</h1><form method="post" action="/update"><input type="hidden" name="id" value="${book.id}"><div class="form-group"><label for="bookname">书名:</label><input type="text" class="form-control" id="bookname" name="bookname" value="${book.bookname}"placeholder="请输入书籍名称"></div><div class="form-group"><label for="price">价格:</label><input type="number" class="form-control" id="price" name="price" value="${book.price}"placeholder="请输入书籍价格"></div><div class="form-group"><label for="booktype">书籍类型:</label><select class="form-control" id="booktype" name="booktype"><option>历史</option><option>言情</option><option>悬疑</option><option>恐怖</option><option>科幻</option><option>诡异</option><option>玄幻</option><option>爱情</option><option>冒险</option><option>热血</option></select></div><button type="submit" class="btn btn-primary">提交</button></form><#else><h1>增加</h1><form method="post" action="/add"><div class="form-group"><label for="bookname">书名:</label><input type="text" class="form-control" id="bookname" name="bookname" value="" placeholder="请输入书籍名称"></div><div class="form-group"><label for="price">价格:</label><input type="number" class="form-control" id="price" name="price" value="" placeholder="请输入书籍价格"></div><div class="form-group"><label for="booktype">书籍类型:</label><select class="form-control" id="booktype" name="booktype"><option>历史</option><option>言情</option><option>悬疑</option><option>恐怖</option><option>科幻</option><option>诡异</option><option>玄幻</option><option>爱情</option><option>冒险</option><option>热血</option></select></div><button type="submit" class="btn btn-primary">提交</button></form></#if>
</body>
</html>

分享就到这里感谢观看,欢迎大家在评论区讨论!

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

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

相关文章

SAP 特殊采购类40--库存转储

我们今天测试一下特殊采购类型40----库存转储 特殊采购类40是我们在系统中进行跨工厂需求传递与跨工厂库存转移的主要手段之一&#xff0c;其核心目的在于将某个工厂中的物料需求传递到另外一个工厂 从PP的角度在去看到话就是有个需求的专递&#xff0c;从MM角度去看这个库存转…

使用Axure RP结合内网穿透工具制作本地静态web页面并实现公网访问

作者简介&#xff1a; 懒大王敲代码&#xff0c;正在学习嵌入式方向有关课程stm32&#xff0c;网络编程&#xff0c;数据结构C/C等 今天给大家讲解使用Axure RP结合内网穿透工具制作本地静态web页面并实现公网访问&#xff0c;希望大家能觉得实用&#xff01; 欢迎大家点赞 &am…

ML流程标准规范汇总

1. 机器学习简介 机器学习是从数据中自动分析获得模型&#xff0c;并利用模型对未知数据进行预测。它是一个流程性很强的工作&#xff0c;包括数据采集、数据清洗、数据预处理、特征工程、模型调优、模型融合、模型验证、模型持久化、在线服务等模块。 而在这些基本的步…

北斗三号短报文+4G的低功耗太阳能船载报位监控方案

国内海洋船舶群体长期在海上航行&#xff0c;多数海员由于海面无信号覆盖、个人卫星通信费用昂贵、无法自由使用船载公用卫星通信设备等原因&#xff0c;无法与家人和朋友保持联系&#xff0c;甚至在遇到危险的时候也无法及时向外界发出求救信号&#xff0c;管理单位难以掌握船…

docker-harbor的私有仓库

目录 harbor的特性 harbor的组件 docker-harbor部署 Docker1 页面访问 ​编辑 上传镜像 创建项目 创建用户 给项目创建成员 上传私有仓库 docker2(远程主机上传) 如何实现仓库之间进行同步 docker3 实现远程仓库同步 仓库 保存镜像 私有&#xff0c;自定义用户…

WPF仿网易云搭建笔记(1):项目搭建

文章目录 前言项目地址动态样式组合样式批量样式覆盖Prism新建UserControler修改Material Design 笔刷收放列表可以滚动的StackPanel列表点击展开或折叠 实现效果 前言 今天接着继续细化代码&#xff0c;把整体框架写出来 项目地址 WPF仿网易云 Gitee仓库 动态样式 【WPF】C#…

企业微信模板卡片消息

投票选择型和多项选择型卡片仅企业微信3.1.12及以上版本支持 文本通知型、图文展示型和按钮交互型三种卡片仅企业微信3.1.6及以上版本支持&#xff08;但附件下载功能仍需更新至3.1.12&#xff09; 微工作台&#xff08;原企业号&#xff09;不支持展示模板卡片消息 文本通知型…

知识库SEO:提升网站内容质量与搜索引擎排名的策略

随着搜索引擎算法的不断更新和优化&#xff0c;单纯依靠关键词堆砌和外部链接的时代已经过去。现在的SEO&#xff08;搜索引擎优化&#xff09;已经转向了以提供高质量、有价值内容为核心的阶段。知识库SEO便是这个新阶段的重要策略之一。 | 一、知识库SEO的概念与意义 1.定义…

【隐私计算】tf-encrypted隐私计算框架/库基础

tf-encrypted介绍 TF Encrypted是TensorFlow中一个用于加密机器学习的框架&#xff0c;它看起来和感觉上都很像TensorFlow&#xff0c;利用了Keras API 的易用性&#xff0c;同时通过安全多方计算和同态加密实现了对加密数据的训练和预测。TF Encrypted的目标是使保护隐私的机器…

关东升老师从小白到大牛系列丛书(由清华大学出版社出版)

助力技术成长&#xff0c;成就大牛之路 在这个科技日新月异的时代&#xff0c;掌握一门编程语言或专业技能已是必备&#xff0c;不再是奢侈。清华大学出版社出版的“从小白到大牛”的系列丛书&#xff0c;涵盖Python、Java、Kotlin、Android和SQL&#xff0c;助你快速在技术之…

严世芸龟法养生经

文章目录 严世芸理念荤素搭配&#xff0c;不偏嗜动静结合心平气和 龟息法 严世芸 严世芸&#xff0c;出生于1940年&#xff0c;现任上海中医药大学的主任医师&#xff0c;教授。他父亲是近代上海有名的中医&#xff0c;他又是著名医家张伯臾的亲传弟子。 从小就在父亲诊室里长…

PO 对象被锁定

问题描述 在创建PO对象的时候&#xff0c;由于上次电脑断网导致PO连接中断&#xff0c;但服务器中登录用户还在占用PO对象&#xff0c;需要手动在POD中删除锁对象才可编辑 解决方案 登录到POD页面&#xff0c;点击右上角Administration 点击Lock Overview&#xff0c;查看…

营销投放下半场,游戏行业如何寻觅进化空间?

摘要&#xff1a;微博&#xff0c;游戏行业突围市场新利器 游戏行业&#xff0c;格局永远在变。 从2017年互联网大厂集体盯上游戏大蛋糕&#xff0c;到2021年行业收缩&#xff0c;再到今年上半年实际销售收入继去年首次出现同比下滑…几经过山车式行情的游戏行业&#xff0c;…

加密友好不意味容易!亚洲地区实施了世界上最严格的加密规定!

2023年的一大主题是亚洲作为加密货币世界中至关重要的地区的持续崛起。这在很大程度上要归功于新加坡等著名的数字资产中心&#xff0c;以及香港和日本的重新崛起。 虽然这些司法管辖区确实欢迎数字资产&#xff0c;但围绕它们的炒作可能会有些误导&#xff0c;加密友好并非意味…

【AI】如何准备mac开发vue项目的环境

为了在Mac上开发Vue项目&#xff0c;你需要准备一些工具和环境。以下是主要的步骤&#xff1a; 安装Node.js和npm&#xff1a; Vue.js是一个基于JavaScript的框架&#xff0c;因此你需要Node.js环境。访问Node.js官网下载并安装Node.js&#xff0c;这也会自动安装npm&#xff0…

玩转大数据18:大规模数据处理与分布式任务调度

引言 在数字化时代&#xff0c;数据成为了一种宝贵的资源&#xff0c;对于企业和组织来说&#xff0c;如何有效地处理和分析这些数据成为了关键的竞争力。大规模数据处理与分布式任务调度作为大数据处理的核心技术&#xff0c;为解决这一问题提供了有效的解决方案。 随着数据…

赛宁网安多领域亮相第三届网络空间内生安全发展大会

2023年12月8日&#xff0c;第三届网络空间内生安全发展大会在宁开幕。两院院士、杰出专家学者和知名企业家相聚南京&#xff0c;围绕数字经济新生态、网络安全新范式进行广泛研讨&#xff0c;为筑牢数字安全底座贡献智慧和力量。 大会围绕“一会、一赛、一展”举办了丰富多彩的…

vue实现滑动验证

效果图&#xff1a; 源码地址&#xff1a;github文档地址&#xff1a; https://github.com/monoplasty/vue-monoplasty-slide-verify 使用步骤&#xff1a;1&#xff0c;安装插件&#xff1a; npm install --save vue-monoplasty-slide-verify 在main.js中使用一下&#xff…

wgcloud访问页面如何加前缀/wgcloud

nginx配置实现加/wgcloud - WGCLOUD

网络层--TCP/UDP协议

目录 一、TCP/UDP协议介绍 1、UDP(User Datagram Protocol)--用户数据报协议 1.1 UDP报文格式 1.2 UDP协议的特性 2、TCP(Transmission Control Protocol )--传输控制协议 2.1 TCP报文格式 2.2 TCP协议的特性 2.3 TCP三次握手 2.4 四次挥手 三、TCP和UDP的区别 四、t…