1 FreeMarker 研究

1.1 FreeMarker介绍

1、freemarker是一个用Java开发的模板引擎

常用的java模板引擎还有哪些?

Jsp、Freemarker、Thymeleaf 、Velocity 等。
2、模板+数据模型=输出

freemarker并不关心数据的来源,只是根据模板的内容,将数据模型在模板中显示并输出文件(通常为html,也可以生成其它格式的文本文件)

1、数据模型

数据模型在java中可以是基本类型也可以List、Map、Pojo等复杂类型。

2、来自官方的例子:(https://freemarker.apache.org/docs/dgui_quickstart_basics.html)

数据模型:


模板:

输出:

1.2 FreeMarker快速入门

freemarker作为springmvc一种视图格式,默认情况下SpringMVC支持freemarker视图格式。

需要创建Spring Boot+Freemarker工程用于测试模板。

1.2.1 创建测试工程

创建一个freemarker 的测试工程专门用于freemarker的功能测试与模板的测试。

pom.xml如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>xc-framework-parent</artifactId><groupId>com.pbteach</groupId><version>1.0-SNAPSHOT</version><relativePath>../xc-framework-parent/pom.xml</relativePath></parent><modelVersion>4.0.0</modelVersion><artifactId>test-freemarker</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-io</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency></dependencies>
</project>

1.2.2 配置文件

配置application.yml和 logback-spring.xml,从cms工程拷贝这两个文件,进行更改, logback-spring.xml无需更改,application.yml内容如下:

server:port: 8088 #服务端口spring:application:name: test-freemarker #指定服务名freemarker:cache: false  #关闭模板缓存,方便测试settings:template_update_delay: 0 #检查模板更新延迟时间,设置为0表示立即检查,如果时间大于0会有缓存不方便进行模板测试

1.2.3 创建模型类

在freemarker的测试工程下创建模型类型用于测试

package com.pbteach.test.freemarker.model;import lombok.Data;
import lombok.ToString;import java.util.Date;
import java.util.List;@Data
@ToString
public class Student {private String name;//姓名private int age;//年龄private Date birthday;//生日private Float money;//钱包private List<Student> friends;//朋友列表private Student bestFriend;//最好的朋友
}

1.2.3 创建模板

在 src/main/resources下创建templates,此目录为freemarker的默认模板存放目录。

在templates下创建模板文件test1.ftl,模板中的${name}最终会被freemarker替换成具体的数据。

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>Hello World!</title>
</head>
<body>
Hello ${name}!
</body>
</html>

1.2.4 创建controller

创建Controller类,向Map中添加name,最后返回模板文件。

package com.pbteach.test.freemarker.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestTemplate;import java.util.Map;@RequestMapping("/freemarker")
@Controller
public class FreemarkerController {@AutowiredRestTemplate restTemplate;@RequestMapping("/test1")public String freemarker(Map<String, Object> map){map.put("name","传智燕青");//返回模板文件名称return "test1";}
}

1.2.5 创建启动类

@SpringBootApplication
public class FreemarkerTestApplication {public static void main(String[] args) {SpringApplication.run(FreemarkerTestApplication.class,args);}
}

1.2.6 测试

请求:http://localhost:8088/freemarker/test1

屏幕显示:Hello 传智燕青!

1.3 FreeMarker基础

1.3.1 核心指令

1.3.1.1 数据模型

Freemarker静态化依赖数据模型和模板,下边定义数据模型:

下边方法形参map即为freemarker静态化所需要的数据模型,在map中填充数据:

@RequestMapping("/test1")public String freemarker(Map<String, Object> map){//向数据模型放数据map.put("name","传智燕青");Student stu1 = new Student();stu1.setName("小明");stu1.setAge(18);stu1.setMondy(1000.86f);stu1.setBirthday(new Date());Student stu2 = new Student();stu2.setName("小红");stu2.setMondy(200.1f);stu2.setAge(19);
//        stu2.setBirthday(new Date());List<Student> friends = new ArrayList<>();friends.add(stu1);stu2.setFriends(friends);stu2.setBestFriend(stu1);List<Student> stus = new ArrayList<>();stus.add(stu1);stus.add(stu2);//向数据模型放数据map.put("stus",stus);//准备map数据HashMap<String,Student> stuMap = new HashMap<>();stuMap.put("stu1",stu1);stuMap.put("stu2",stu2);//向数据模型放数据map.put("stu1",stu1);//向数据模型放数据map.put("stuMap",stuMap);//返回模板文件名称return "test1";}

1.3.1.2 List指令

本节定义freemarker模板,模板中使用freemarker的指令,关于freemarker的指令需要知道:

1、注释,即<#--和-->,介于其之间的内容会被freemarker忽略
2、插值(Interpolation):即${..}部分,freemarker会用真实的值代替${..}
3、FTL指令:和HTML标记类似,名字前加#予以区分,Freemarker会解析标签中的表达式或逻辑。
4、文本,仅文本信息,这些不是freemarker的注释、插值、FTL指令的内容会被freemarker忽略解析,直接输出内容。

在test1.ftl模板中使用list指令遍历数据模型中的数据:

<table><tr><td>序号</td><td>姓名</td><td>年龄</td><td>钱包</td></tr><#list stus as stu><tr><td>${stu_index + 1}</td><td>${stu.name}</td><td>${stu.age}</td><td>${stu.mondy}</td></tr></#list></table>

3、输出:

Hello 传智燕青!

序号 姓名 年龄 钱包

1 小明 18 1,000.86

2 小红 19 200.1

说明:
_index:得到循环的下标,使用方法是在stu后边加"_index",它的值是从0开始

1.3.1.3 遍历Map数据

1、数据模型

使用map指令遍历数据模型中的stuMap。

2、模板

输出stu1的学生信息:<br/>
姓名:${stuMap['stu1'].name}<br/>
年龄:${stuMap['stu1'].age}<br/>
输出stu1的学生信息:<br/>
姓名:${stuMap.stu1.name}<br/>
年龄:${stuMap.stu1.age}<br/>
遍历输出两个学生信息:<br/>
<table><tr><td>序号</td><td>姓名</td><td>年龄</td><td>钱包</td></tr>
<#list stuMap?keys as k>
<tr><td>${k_index + 1}</td><td>${stuMap[k].name}</td><td>${stuMap[k].age}</td><td >${stuMap[k].mondy}</td>
</tr>
</#list>
</table>

3、输出

输出stu1的学生信息:
姓名:小明
年龄:18
输出stu1的学生信息:
姓名:小明
年龄:18
遍历输出两个学生信息:
序号  姓名  年龄  钱包
1   小红  19  200.1
2   小明  18  1,000.86

1.3.1.4 if指令

if 指令即判断指令,是常用的FTL指令,freemarker在解析时遇到if会进行判断,条件为真则输出if中间的内容,否则跳过内容不再输出。

1、数据模型:

使用list指令中测试数据模型。

2、模板:

<table><tr><td>姓名</td><td>年龄</td><td>钱包</td></tr><#list stus as stu><tr><td <#if stu.name =='小明'>style="background:red;"</#if>>${stu.name}</td><td>${stu.age}</td><td >${stu.mondy}</td></tr></#list></table>

通过阅读上边的代码,实现的功能是:如果姓名为“小明”则背景色显示为红色。

3、输出:

通过测试发现 姓名为小明的背景色为红色。

1.3.2 其它指令

1.3.2.1 运算符

1、算数运算符

FreeMarker表达式中完全支持算术运算,FreeMarker支持的算术运算符包括:+, - , * , / , %

2、逻辑运算符

逻辑运算符有如下几个:

逻辑与:&&

逻辑或:||

逻辑非:!

逻辑运算符只能作用于布尔值,否则将产生错误

3、比较运算符

表达式中支持的比较运算符有如下几个:

1 =或者==:判断两个值是否相等.

2 !=:判断两个值是否不等.

3 >或者gt:判断左边值是否大于右边值

4 >=或者gte:判断左边值是否大于等于右边值

5 <或者lt:判断左边值是否小于右边值

6 <=或者lte:判断左边值是否小于等于右边值

注意: =和!=可以用于字符串,数值和日期来比较是否相等,但=和!=两边必须是相同类型的值,否则会产生错误,而且FreeMarker是精确比较,“x”,"x ","X"是不等的.其它的运行符可以作用于数字和日期,但不能作用于字符串,大部分的时候,使用gt等字母运算符代替>会有更好的效果,因为 FreeMarker会把>解释成FTL标签的结束字符,当然,也可以使用括号来避免这种情况,如:<#if (x>y)>

1.3.2.2 空值处理

1、判断某变量是否存在使用 “??”

用法为:variable??,如果该变量存在,返回true,否则返回false

例:为防止stus为空报错可以加上判断如下:

    <#if stus??><#list stus as stu>......</#list></#if>

2、缺失变量默认值使用 “!”

使用!要以指定一个默认值,当变量为空时显示默认值。

例: ${name!’’}表示如果name为空显示空字符串。

如果是嵌套对象则建议使用()括起来。

例: ${(stu.bestFriend.name)!’’}表示,如果stu或bestFriend或name为空默认显示空字符串。

1.3.2.3 内建函数

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

1、和到某个集合的大小

${集合名?size}

2、日期格式化

显示年月日: ${today?date}
显示时分秒:${today?time}
显示日期+时间:${today?datetime} <br>
自定义格式化:  ${today?string("yyyy年MM月")}

3、内建函数c

map.put(“point”, 102920122);

point是数字型,使用${point}会显示这个数字的值,不并每三位使用逗号分隔。

如果不想显示为每三位分隔的数字,可以使用c函数将数字型转成字符串输出

${point?c}

4、将json字符串转成对象

一个例子:

其中用到了 assign标签,assign的作用是定义一个变量。

<#assign text="{'bank':'工商银行','account':'10101920201920212'}" />
<#assign data=text?eval />
开户行:${data.bank}  账号:${data.account}

1.3.2.4 完整的模板

上边测试的模板内容如下,可自行进行对照测试。

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>Hello World!</title>
</head>
<body>
Hello ${name}!
<br/>
<table><tr><td>序号</td><td>姓名</td><td>年龄</td><td>钱包</td></tr><#list stus as stu><tr><td>${stu_index + 1}</td><td <#if stu.name =='小明'>style="background:red;"</#if>>${stu.name}</td><td>${stu.age}</td><td >${stu.mondy}</td></tr></#list></table>
<br/><br/>
输出stu1的学生信息:<br/>
姓名:${stuMap['stu1'].name}<br/>
年龄:${stuMap['stu1'].age}<br/>
输出stu1的学生信息:<br/>
姓名:${stu1.name}<br/>
年龄:${stu1.age}<br/>
遍历输出两个学生信息:<br/>
<table><tr><td>序号</td><td>姓名</td><td>年龄</td><td>钱包</td></tr>
<#list stuMap?keys as k>
<tr><td>${k_index + 1}</td><td>${stuMap[k].name}</td><td>${stuMap[k].age}</td><td >${stuMap[k].mondy}</td>
</tr>
</#list>
</table>
</br>
<table><tr><td>姓名</td><td>年龄</td><td>出生日期</td><td>钱包</td><td>最好的朋友</td><td>朋友个数</td><td>朋友列表</td></tr><#if stus??><#list stus as stu><tr><td>${stu.name!''}</td><td>${stu.age}</td><td>${(stu.birthday?date)!''}</td><td>${stu.mondy}</td><td>${(stu.bestFriend.name)!''}</td><td>${(stu.friends?size)!0}</td><td><#if stu.friends??><#list stu.friends as firend>${firend.name!''}<br/></#list></#if></td></tr></#list></#if></table>
<br/>
<#assign text="{'bank':'工商银行','account':'10101920201920212'}" />
<#assign data=text?eval />
开户行:${data.bank}  账号:${data.account}</body>
</html>

1.3.3 静态化测试

在cms中使用freemarker将页面生成html文件,本节测试html文件生成的方法:

1、使用模板文件静态化

定义模板文件,使用freemarker静态化程序生成html文件。

2、使用模板字符串静态化

定义模板字符串,使用freemarker静态化程序生成html文件。

1.3.3.1 使用模板文件静态化

在test下创建测试类,并且将main下的resource/templates拷贝到test下,本次测试使用之前我们在main下创建的模板文件。

//基于模板生成静态化文件
@Test
public void testGenerateHtml() throws IOException, TemplateException {//创建配置类Configuration configuration=new Configuration(Configuration.getVersion());//设置模板路径String classpath = this.getClass().getResource("/").getPath();configuration.setDirectoryForTemplateLoading(new File(classpath + "/templates/"));//设置字符集configuration.setDefaultEncoding("utf-8");//加载模板Template template = configuration.getTemplate("test1.ftl");//数据模型Map<String,Object> map = new HashMap<>();map.put("name","传智燕青");//静态化String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);//静态化内容System.out.println(content);InputStream inputStream = IOUtils.toInputStream(content);//输出文件FileOutputStream fileOutputStream = new FileOutputStream(new File("d:/test1.html"));int copy = IOUtils.copy(inputStream, fileOutputStream);
}

1.3.3.2 使用模板字符串静态化

//基于模板字符串生成静态化文件
@Test
public void testGenerateHtmlByString() throws IOException, TemplateException {//创建配置类Configuration configuration=new Configuration(Configuration.getVersion());//模板内容,这里测试时使用简单的字符串作为模板String templateString="" +"<html>\n" +"    <head></head>\n" +"    <body>\n" +"    名称:${name}\n" +"    </body>\n" +"</html>";//模板加载器StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();stringTemplateLoader.putTemplate("template",templateString);configuration.setTemplateLoader(stringTemplateLoader);//得到模板Template template = configuration.getTemplate("template","utf-8");//数据模型Map<String,Object> map = new HashMap<>();map.put("name","传智燕青");//静态化String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);//静态化内容System.out.println(content);InputStream inputStream = IOUtils.toInputStream(content);//输出文件FileOutputStream fileOutputStream = new FileOutputStream(new File("d:/test1.html"));IOUtils.copy(inputStream, fileOutputStream);
}

Freemarker页面静态化相关推荐

  1. freemarker 页面静态化技术

    文章目录 一.背景 二.页面静态化技术freemarker 三.Freemarker基本操作 1.引入依赖: 2.创建模板文件: 3.FTL指令: 四.freemarker整合spring 五.总结: ...

  2. freemarker java静态方法_java Freemarker页面静态化实例详解

    freemarker freemarker 是一个用 java 语言编写的模板引擎,它基于模板来生成文本输出.freemarker与 web 容器无关,即在 web 运行时,它并不知道 servlet ...

  3. Freemarker 页面静态化技术使用入门案例

    在访问 新闻.活动.商品 详情页面时, 路径可以是 xx[id].html, 服务器端根据请求 id, 动态生成 html 网页,下次访问数据时,无需再查询数据,直接将 html 静态页面返回.这样一 ...

  4. 11(maven+SSH)网上商城项目实战之Freemarker 页面静态化

    FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写 l         FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式的应用程序 ...

  5. 【工具类】页面静态化 --- Freemarker的使用

    介绍 FreeMarker 是一个用 Java 语言编写的模板引擎,它基于模板来生成文本输出.FreeMarker与 Web 容器无关,即在 Web 运行时,它并不知道 Servlet 或 HTTP. ...

  6. 使用Freemarker来页面静态化,与Spring整合使用

    页面静态化介绍 页面静态化其实就是将原来的动态网页(例如通过ajax请求动态获取数据库中的数据并展示的网页)改为 通过静态化技术生成的静态网页,这样用户在访问网页时,服务器直接给用户响应静态html页 ...

  7. SpringBoot2 整合FreeMarker模板,完成页面静态化处理

    本文源码:GitHub·点这里 || GitEE·点这里 一.页面静态化 1.动静态页面 静态页面 即静态网页,指已经装载好内容HTML页面,无需经过请求服务器数据和编译过程,直接加载到客户浏览器上显 ...

  8. freemarker之页面静态化

    静态化? 这里我们以网页静态化技术之一的Freemarker 为例子.以电商为原型 对于电商网站的商品详情页来说,至少几百万个商品,每个商品又有大量的信息,这样的情况同样也适用于使用网页静态化来解决 ...

  9. JavaWeb(14) 页面静态化之使用freemarker模板生成一个html静态页面

    题外话:        页面静态化(展示数据从JSP页面变成HTML页面)实现方式-->模板技术   从本质上来讲,模板技术是一个占位符动态替换技术.一个完整的模板技术需要四个元素:①模板语言( ...

最新文章

  1. 导入python库linux_Linux下Python安装PyMySQL成功,但无法导入的问题
  2. php中类的构造函数是,php类与构造函数解析
  3. Sequelize 4.42.1 发布,基于 Nodejs 的异步 ORM 框架
  4. 通过一个例子来理解二维码纠错机制
  5. Python 包含\u字符串转中文(\u00)
  6. 亚马逊率先用Sun新推OpenSolaris系统
  7. 传奇电子cq9跳高高、跳起来规则与操作技巧
  8. 定时任务:java 中Timer 和 TimerTask 的使用
  9. fetch与axios
  10. 双击 计算机 网络打不开,windows7系统双击“双击计算机”打不开怎么回事
  11. CKEditor 实例
  12. python设计模式之策略模式
  13. ffmpeg截取jpg图_使用ffmpeg进行视频封面截取
  14. 基础软件“好用”指南:必须跨越这两道鸿沟!
  15. oracle rman list,Oracle RMAN的show,list,crosscheck,delete
  16. SpCL阅读笔记:Self-paced Contrastive Learning with Hybrid Memory for Domain Adaptive Object Re-ID
  17. android web 爬虫,Android学习——Jsoup实现网络爬虫,爬取贤集网
  18. java学习总结(16.07.16)Random类和BigDecimal类
  19. python3爬虫抓取链家上海租房信息
  20. X509Certificate

热门文章

  1. 概率及常用概率分布的实现——计算机视觉修炼之路(零)
  2. exp报错与exp为何导不出某些表结构原因
  3. 生。老。病。死。求不得,爱别离,怨憎会,五阴炽盛。怜众生无知,取苦为乐,饮鸩止渴。...
  4. app调用微信支付接口第一次成功,后面就调取不成功
  5. 水电抄表预付费一体化平台
  6. 详解:生产线平衡调节方法与步骤说明!
  7. Request请求转发详解
  8. 3d游戏开发相关概念_游戏开发概念
  9. 【个人刷题笔记】1007 Maximum Subsequence Sum (25 分)最大子段和简单DP,一堆坑
  10. 新房自己装修好还是找公司好?