首页 > 其他分享 >使用 FreeMarker 生成静态页面

使用 FreeMarker 生成静态页面

时间:2024-01-22 22:22:06浏览次数:29  
标签:map name FreeMarker 静态 empMap emp 模板 页面

在项目开发中,对于一些访问量较大的页面,可以提前基于数据生成静态页面,当数据有变化时再重新生成并更新静态页面,这样可以减轻数据库压力,提高网站的并发访问效率。常用的技术就是使用 FreeMarker 模板引擎,它是一款高性能的,基于模板和数据, 生成输出文本的通用工具。本篇博客基于 FreeMarker 的常用指令,介绍如何生成静态页面,在博客最后会提供源代码下载。

FreeMarker 的官网地址是:https://freemarker.apache.org/index.html


一、搭建工程

新建一个 springboot 工程,名称为 springboot_freemarker,结构如下:

image

pom 文件引用的依赖包如下所示:

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.jobs</groupId>
    <artifactId>springboot_freemarker</artifactId>
    <version>1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
    </parent>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--引入 freemarker 的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.4.5</version>
            </plugin>
        </plugins>
    </build>
</project>

最主要的是引入了 spring-boot-starter-freemarker 依赖包,然后配置文件如下:

server:
  port: 8080
spring:
  freemarker:
    # 关闭模板缓存
    cache: false
    # 设置模板文件的后缀名,默认值是 .ftlh
    suffix: .ftlh
    # 设置模板的目录,默认值是 classpath:/templates/
    template-loader-path: classpath:/templates/

这里使用的都是 FreeMarker 的默认配置,默认的模板文件存放位置是 resources 下的 templates 目录,默认的模板文件的后缀名是 .ftlh,默认也关闭缓存。在使用 FreeMarker 生成静态页面之前,我们最好能够通过浏览器访问页面,查看数据和模板结合的效果。由于 SpringMvc 默认就支持 FreeMarker 视图格式,因此本篇博客的 Demo 提供 Controller 访问地址,通过浏览器可以实际效果。本篇博客的 Demo 在测试类 FreemarkTest 中实现了生成静态页面的代码。


二、代码详细介绍

Controller 类中的代码与 FreeMarkerTest 类中的代码一样,这里就不列出了,为了减少篇幅冗余,这里直接列出生成静态页面的代码,另外在 Freemarker 模板里面,注释也很详细,相信大家应该能够看懂。这里只列出常用的 FreeMarker 指令,如果想了解更多指令,可以参考官网。

首先看一下 Demo 中的实体类 Employee 内容:

package com.jobs.pojo;

import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class Employee {

    //员工姓名
    private String name;

    //员工年龄
    private Integer age;

    //员工部门
    private String depart;
}

然后看一下 Sample.ftlh 模板的内容,这个里面使用了一些简单的指令:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>简单用法展示</title>
</head>
<body>

<b>普通文本展示:</b><br/>
<#--【变量!默认值】表示如果变量为 null,则使用默认值-->
员工姓名为:${name!'name 为null,这里显示默认文本'}<br/>
<hr>

<b>对象实例中的数据展示:</b><br/>
<#--【(变量.属性)!默认值】表示如果变量为 null 或者变量的属性为 null,则使用默认值-->
员工姓名:${(emp.name)!'姓名默认值'}<br/>
员工年龄:${(emp.age)!38}<br/>
员工部门:${(emp.depart)!'部门默认值'}<br/>
<hr>

<b>数字展示:</b><br/>
默认数字展示带有逗号:${num}<br/>
<#--【变量?c】如果变量是数字,可以取消显示数字中的逗号-->
取消数字中的逗号:${num?c}<br/>
<hr>

<b>日期时间展示展示:</b><br/>
日期展示:${today?date}<br/>
时间展示:${today?time}<br/>
日期时间展示:${today?datetime}<br/>
自定义展示:${today?string("yyyy年MM月dd日 HH时mm分ss秒")}<br/>
<hr>

<b>json字符串转对象:</b><br/>
<#--【变量?eval】如果变量是 json 字符串,可以转换为对象-->
<#assign emp="${jsonStr}"?eval/>
json中的姓名:${(emp.name)!'姓名默认值'}<br/>
json中的年龄:${(emp.age)!0}<br/>

</body>
</html>

然后再看一下 list_map.flth 模板,这里面使用了 list 集合和 map 集合的一些常用指令:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>列表数据和map数据的展示</title>
</head>
<body>

<#-- list 数据的展示 -->
<b>展示 list 中的数据:</b><br>
<table border="1" cellpadding="1" cellspacing="1">
    <tr>
        <td>序号</td>
        <td>姓名</td>
        <td>年龄</td>
        <td>部门</td>
    </tr>
    <#--【变量??】表示判断变量是否为 null,如果不为 null 则执行下面的代码-->
    <#if empList??>
    <#--list【变量】as【变量】表示循环遍历list中的每一条数据-->
        <#list empList as emp>
            <#if emp_index%2=0>
                <tr style="background-color: lightyellow">
                    <td>${emp_index + 1}</td>
                    <td>${emp.name}</td>
                    <td>${emp.age}</td>
                    <td>${emp.depart}</td>
                </tr>
            <#else>
                <tr>
                    <td>${emp_index + 1}</td>
                    <td>${emp.name}</td>
                    <td>${emp.age}</td>
                    <td>${emp.depart}</td>
                </tr>
            </#if>
        </#list>
    </#if>
</table>
<br>

<#--list【变量】?size 表示获取列表的大小-->
<#if empList??>
    list集合的大小为:${empList?size}
</#if>
<hr>

<#-- Map 数据的展示 -->
<b>展示 map 中的数据:</b><br/>
通过 map['keyname'].property 获取数据:<br/>
姓名:${empMap['emp1'].name}<br/>
年龄:${empMap['emp1'].age}<br/>
部门:${empMap['emp1'].depart}<br/>
<br/>

通过map.keyname.property 获取数据:<br/>
姓名:${empMap.emp2.name}<br/>
年龄:${empMap.emp2.age}<br/>
部门:${empMap.emp2.depart}<br/>
<br/>

遍历 map 中的数据:
<table border="1" cellpadding="1" cellspacing="1">
    <tr>
        <td>序号</td>
        <td>姓名</td>
        <td>年龄</td>
        <td>员工</td>
    </tr>
    <#if empMap??>
        <#list empMap?keys as key>
            <tr>
                <td>${key_index + 1}</td>
                <td>${empMap[key].name}</td>
                <td>${empMap[key].age}</td>
                <td>${empMap[key].depart}</td>
            </tr>
        </#list>
    </#if>
</table>
<br/>

<#if empMap??>
    map集合的大小为:${empMap?keys?size}
</#if>
</body>
</html>

最后我们在 FreeMarkerTest 类中,自己造一些数据,然后使用上面的 2 个模板生成静态页面:

package com.jobs;

import com.jobs.pojo.Employee;
import freemarker.template.Template;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.FileWriter;
import java.util.*;

@SpringBootTest
public class FreemarkerTest {

    @Autowired
    private freemarker.template.Configuration configuration;

    @Test
    void createSampleHtmlPage() throws Exception {
        //获取模板
        Template template = configuration.getTemplate("sample.ftlh");
        //获取数据
        Map data = getSampleData();
        //生成静态页面
        template.process(data, new FileWriter("d:/sample.html"));
    }


    @Test
    void createListMapPage() throws Exception {
        //获取模板
        Template template = configuration.getTemplate("list_map.ftlh");
        //获取数据
        Map data = getListMapData();
        //生成静态页面
        template.process(data, new FileWriter("d:/listmap.html"));
    }


    Map getSampleData() {
        Map<String, Object> map = new HashMap<>();

        //普通文本展示
        map.put("name", "乔豆豆");

        //对象实例中的数据展示
        Employee emp = new Employee().setName("任肥肥")
                .setAge(36).setDepart("技术部");
        map.put("emp", emp);

        //数字展示
        map.put("num", 123456789L);

        //日期时间展示展示
        map.put("today", new Date());

        //json字符串转对象
        String json = "{'name':'侯胖胖','age':38}";
        map.put("jsonStr", json);

        return map;
    }

    Map getListMapData() {
        Map<String, Object> map = new HashMap<>();

        Employee emp1 = new Employee().setName("任肥肥").setAge(36).setDepart("运营部");
        Employee emp2 = new Employee().setName("侯胖胖").setAge(38).setDepart("技术部");
        Employee emp3 = new Employee().setName("乔豆豆").setAge(40).setDepart("销售部");

        //添加到 list 中
        List<Employee> empList = new ArrayList<>();
        empList.add(emp1);
        empList.add(emp2);
        empList.add(emp3);
        map.put("empList", empList);

        //添加到 map 中
        Map<String, Employee> empMap = new HashMap<>();
        empMap.put("emp1", emp1);
        empMap.put("emp2", emp2);
        empMap.put("emp3", emp3);
        map.put("empMap", empMap);

        return map;
    }
}

三、实际效果

运行 2 个测试方法,代码中是将静态页面生成到了 d 盘目录中。

其中 createSampleHtmlPage 测试方法,生成的静态页面效果如下:

image

测试方法 createListMapPage 生成的静态页面,效果如下:

image


本篇博客的源代码下载地址为:https://files.cnblogs.com/files/blogs/699532/springboot_freemarker.zip

标签:map,name,FreeMarker,静态,empMap,emp,模板,页面
From: https://www.cnblogs.com/studyjobs/p/17981208

相关文章

  • 无涯教程-CodeIgniter - 页面重定向
    在构建Web应用程序时,无涯教程经常需要将用户从一个页面重定向到另一页面。redirect()函数用于此目的。语法redirect($uri='',$method='auto',$code=NULL)参数$uri(string)     -URI字符串$method(string)-重定向方法("auto","location"或"refresh")$......
  • 无涯教程-CodeIgniter - 页面缓存
    缓存页面将提高页面加载速度。缓存的文件存储在application/cache文件夹中。启用缓存时,需要设置缓存时间,时间过后,将自动被删除。启用缓存可以通过在控制器的任何方法中执行以下行来启用缓存。$this->output->cache($n);其中$n是分钟数,您希望页面在刷新之间保持高速缓存。......
  • 一个十分有趣的文档页面
    我的博客里有一个devops页面,专门用来汇总我写过的一些DevOps运维自动化相关的技术文章,页面很简单,就是一段文字描述加上一堆的文章链接,像下面这个样子一直以来这个页面都安安静静的存在着,访问者甚少,像是一个默默无闻没人关注的孩子,躲在角落里,偶尔有人来看上两眼,也会因为他的丑陋......
  • 代码静态测试工具Helix QAC 2023.4新发布
    喜欢本篇文章速速点赞评论⭐收藏 HelixQAC2023.4为新的MISRAC++:2023指南推出了100%MISRAC++:2023®规则覆盖率。此版本还包括扩展的C++20语言支持、数据流分析的性能改进以及整个产品中的许多产品体验增强功能。 Jumpto你喜欢的部分 增强对C++20的支持......
  • Centos 静态IP网卡格式
    TYPE="Ethernet"PROXY_METHOD="none"BROWSER_ONLY="no"BOOTPROTO="static"修改该项dhcp为staticIPADDR=192.168.1.129增加静态IP地址NETMASK=255.255.255.0子网掩码GATEWAY=192.168.1.1子网网关DNS1=114.114.114.114DNSDE......
  • ohos.router (页面路由) 框架
    UIAbility概述UIAbility是一种包含用户界面的应用组件,主要用于和用户进行交互。UIAbility也是系统调度的单元,为应用提供窗口在其中绘制界面。每一个UIAbility实例,都对应于一个最近任务列表中的任务。一个应用可以有一个UIAbility,也可以有多个UIAbility,如下图所示。例如浏览器......
  • Feign源码解析7:nacos loadbalancer不支持静态ip的负载均衡
    背景在feign中,一般是通过eureka、nacos等获取服务实例,但有时候调用一些服务时,人家给的是ip或域名,我们这时候还能用Feign这一套吗?可以的。有两种方式,一种是直接指定url:这种是服务端自己会保证高可用、负载均衡那些。但也可能对方给了多个url(一般不会这样,但是在app场景下,为了......
  • 小程序开发:修复了两个问题和页面改名
    今天发现首页的笔记本的徽标数位置不一致,如果笔记本标题长了,徽标数也会挤到其它位置去,如下: 很明显两个徽标的位置不一致,html结构如下: 将徽标和标题调整如下: 再看看页面: 解决!还有一个问题是新增所思所想如果内容区只有html元素,如:img、换行等都被视为html......
  • uniapp+django登录页面实现
    前后端联动概述以一个简单的登录功能为例说明,uni-app的前后端交互项目地址:效果图前端页面开发项目地址:后端页面开发项目地址:其他参考资料1、Django项目和uni-app项目的创建及项目文件讲解https://blog.csdn.net/qq_55002406/article/details/1287887882、如何将前......
  • Centos7 nat网络模式静态ip配置。
    配置流程:1.本机找到 VMwareNetworkAdapterVMnet8,然后配置ipv4: 2:vm里找到编辑->虚拟网络编辑器,然后按第一步里配置的信息来配置 VMwareNetworkAdapterVMnet8里的网关这些。   3:进入centos7系统,配置ifcfg-ens33,vi /etc/sysconfig/network-scripts/ifcfg......