FreeMarker自动页面静态化生成html文件

自动页面静态化

用代码自动把模板和数据模型结合起来,最终输出一个有数据的静态页面,静态页面因为是它的数据已经没有和后端交互了

FreeMarker

个人了解 FreeMarker和JSP、thymeleaf等是一种模板引擎,反正我觉得前端页面语法它和JSP的都差不多,后端的准备数据模型和thymeleaf差不多,用Model和Map存数据都行。

实现

其实实现非常直观简单,利用FreeMarker的配置工具将你要生成的页面的模板的资源路径和数据模型准备好,然后配置工具会返回一个字符串, 这个字符串就是页面的html了,最后用输出流将其创建并写入文件就生成html文件了
在这里插入图片描述

项目目录结构:
在这里插入图片描述
将resources文件夹挪到test测试文件夹下, 把properties文件可以删掉。目的是调用.ftl页面资源

我们将FreeMarker自动页面静态化生成html文件的程序放到单元测试中完成:

package com.xuecheng.test.freemarker;

import com.xuecheng.test.freemarker.model.Student;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UnitTest {

    //测试静态化,基于ftl模板文件生成html
    //单纯用FreeMarker来打包生成html文件,与平时结合SpringBoot来展示FreeMarker页面不相同
    @Test
    public void test() throws IOException, TemplateException {
        //定义配置类
        Configuration configuration = new Configuration(Configuration.getVersion());
        //获取当前类的target下的的test-classes目录路径
        String path = this.getClass().getResource("/").getPath();
        //定义模板--设置模板路径
        configuration.setDirectoryForTemplateLoading(new File(path + "/templates/"));
        //设置模板文件
        Template template = configuration.getTemplate("test1.ftl");
        //数据模型
        Map map = getMap();
        //将模板和数据模型结合生成html文本
        String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
        //将html内容存到输入流中
        InputStream inputStream = IOUtils.toInputStream(content);
        //创建文件test1.html
        FileOutputStream outputStream = new FileOutputStream(new File("D:/test1.html"));
        //将输入流中的html文本内容输送到输出流创建的文件中
        IOUtils.copy(inputStream, outputStream);

        //关闭流
        inputStream.close();
        outputStream.close();

		//System.out.println(content);

    }
	
	//准备test1.ftl页面的数据模型
    public Map getMap(){
        HashMap<String, Object> map = new HashMap<>();
        map.put("name","黑马程序员");
        Student stu1 = new Student();
        stu1.setName("小明");
        stu1.setAge(18);
        stu1.setMoney(1000.86f);
        stu1.setBirthday(new Date());
        Student stu2 = new Student();
        stu2.setName("小红");
        stu2.setMoney(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);
        map.put("point", 102920122);
        return map;
    }
}

我觉得全部代码的核心就是这句,其他都是浮云

 //将模板和数据模型结合生成html文本
 String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);

此处的流是采用的apche的,其实我们也可以用普通的流来实现,但性能不知道有没有区别。

 //将模板和数据模型结合生成html文本
 String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
  //将html内容存到输入流中
  InputStream inputStream = IOUtils.toInputStream(content);
  //创建文件test1.html
  FileOutputStream outputStream = new FileOutputStream(new File("D:/test1.html"));
  //将输入流中的html文本内容输送到输出流创建的文件中
  IOUtils.copy(inputStream, outputStream);

普通输出流

//html文本
 String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
//输出流
File f = new File("d:/test1.html");
FileWriter fw = new FileWriter(f, false);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter pw = new PrintWriter(bw);
pw.println(content);
pw.flush();

两种流实现的结果都是一样的, 都是生成一个html文件

补:基于模板文件内容(字符串),生成html文件: 字符串 + 数据模型 -> html文件
实现方法和上面的方法其实差不多,只是模板的来源不一样而已,上面的是已有的模板,而这个是仅有字符串,但其实也差不多。。
但这种方法比上面的方法灵活,因为这中可以通过用户输入字符串或者从文件中提取字符串从而创建一个静态化页面

//基于模板文件内容(字符串),生成Html文件 字符串 + 数据模型 -> html文件
@Test
public void test02() throws IOException, TemplateException {
    //定义配置类
    Configuration configuration = new Configuration(Configuration.getVersion());

    //字符串内容,这里测试时使用简单的字符串作为模板内容,但此时这模板仍没有数据,若想要和数据结合,必须将此字符串变成模板类型
    String templateString="" +
            "<html>\n" +
            " <head></head>\n" +
            " <body>\n" +
            " 名称:${name}\n" +
            " </body>\n" +
            "</html>";
    //使用FreeMarker模板加载器将templateString字符串变成模板
    StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
    stringTemplateLoader.putTemplate("template", templateString);
    //在配置中设置模板加载器并生成模板
    configuration.setTemplateLoader(stringTemplateLoader);
    //获取模板
    Template template = configuration.getTemplate("template", "utf-8");
    //-------------------------下面和test方法的步骤一样了,就是生成html文件了-------------------------
    Map map = getMap();
    //静态化
    String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
    //将html内容存到输入流中
    InputStream inputStream = IOUtils.toInputStream(content);
    //创建文件test1.html
    FileOutputStream outputStream = new FileOutputStream(new File("D:/test1.html"));
    //将输入流中的html文本内容输送到输出流创建的文件中
    IOUtils.copy(inputStream, outputStream);

    //关闭流
    inputStream.close();
    outputStream.close();
}
发布了86 篇原创文章 · 获赞 1 · 访问量 4338

猜你喜欢

转载自blog.csdn.net/qq_42039738/article/details/105168742