java Freemarker页面静态化实例详解

Java FreeMarker页面静态化实例详解

什么是FreeMarker页面静态化

FreeMarker是一款基于模板技术实现的Java模板引擎,它可以将动态的HTML页面转化成静态的HTML页面,将一个基于模板的数据模型填充到模板中生成完整的HTML页面,并将HTML页面中的占位符等内容替换成相应的数据,将页面的内容动态的生成并输出。FreeMarker页面静态化是指将服务器端渲染的动态网页,由Java程序定时或者触发器方式生成静态化HTML页面,减少服务器直接处理动态页面的消耗,避免网站被大流量打崩。

实现步骤

  1. 引入FreeMarker依赖

在Maven中可以添加如下的依赖:

<dependency>
  <groupId>org.freemarker</groupId>
  <artifactId>freemarker</artifactId>
  <version>2.3.23</version>
</dependency>
  1. 构建FreeMarker配置类

构建一个FreeMarker配置类,配置模板和静态页面的存储位置

@Configuration
public class FreeMarkerConfig {

    @Value("${spring.freemarker.template-loader-path}")
    private String templateLoaderPath;

    @Value("${spring.freemarker.static-file-loader-path}")
    private String staticFileLoaderPath;

    @Bean
    public FreeMarkerConfigurationFactoryBean freeMarkerConfigurationFactoryBean() throws IOException {
        FreeMarkerConfigurationFactoryBean bean = new FreeMarkerConfigurationFactoryBean();
        bean.setTemplateLoaderPath(templateLoaderPath);
        // 设置页面名称和路径
        Map<String, String> nameMapping = new HashMap<>();
        nameMapping.put("test.ftl", "test.html");
        bean.setFreemarkerVariables(Collections.singletonMap("nameMapping", nameMapping));
        Properties settings = new Properties();
        settings.setProperty(freemarker.template.Configuration.TEMPLATE_UPDATE_DELAY_KEY, "5000");
        bean.setFreemarkerSettings(settings);
        return bean;
    }

    @Bean
    public FreeMarkerConfigurer freeMarkerConfigurer(FreeMarkerConfigurationFactoryBean bean) throws IOException {
        FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
        configurer.setConfiguration(bean.getObject());
        configurer.setDefaultEncoding("UTF-8");
        configurer.setPreferFileSystemAccess(false);
        Map<String, String> mappings = new HashMap<>();
        mappings.put("*.ftl", "*.html");
        configurer.setFreemarkerMappings(mappings);
        configurer.setFreeMarkerVariables(Collections.singletonMap("STATIC_FILE_LOADER",
        staticFileLoaderPath));
        return configurer;
    }

}
  1. 构建Java模板引擎工具类

构建一个工具类,用于将Java对象转化为Map,并结合相应的模板文件生成静态的HTML文件。

@Service
public class FreeMarkerService {

    @Autowired
    private Configuration configuration;

    public void toHtml(String templateName, String staticFileName, Object data) throws Exception {
        // 获取模板
        Template template = configuration.getTemplate(templateName);
        // 设置静态化文件路径
        String path = "./static/" + staticFileName;
        // 获取输出流
        FileWriter fileWriter = new FileWriter(path);
        // 渲染模板生成静态文件
        template.process(data, fileWriter);
        // 关闭输出流
        fileWriter.close();
    }

    public Map<String, Object> objectToMap(Object obj) throws Exception {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<>();
        BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor property : propertyDescriptors) {
            String key = property.getName();

            if (key.compareToIgnoreCase("class") == 0) {
                continue;
            }
            Method getter = property.getReadMethod();
            Object value = getter == null ? null : getter.invoke(obj);
            map.put(key, value);
        }
        return map;
    }

    public void toHtmlFromObject(String templateName, String staticFileName, Object obj) throws Exception {
        Map<String, Object> map = objectToMap(obj);
        toHtml(templateName, staticFileName, map);
    }

}
  1. 构建测试类

在测试类中使用方法toHtmlFromObject:将数据模型填充到模板中生成完整的HTML页面,并将HTML页面中的占位符等内容替换成相应的数据。

示例

以模拟网站电商商品详情页面,生成一个符合静态页面的html作为例子,具体步骤如下:

  1. 引入依赖

在Maven中添加FreeMarker依赖,pom.xml中的配置如下:

<dependency>
  <groupId>org.freemarker</groupId>
  <artifactId>freemarker</artifactId>
  <version>2.3.23</version>
</dependency>
  1. 配置FreeMarker

配置FreeMarker的模板和静态文件的存储位置,代码如下:

@Configuration
public class FreeMarkerConfig {

    @Value("${spring.freemarker.template-loader-path}")
    private String templateLoaderPath;

    @Value("${spring.freemarker.static-file-loader-path}")
    private String staticFileLoaderPath;

    // 通过此方法创建FreeMarkerConfigurationFactoryBean,配置FreeMarker
    @Bean
    public FreeMarkerConfigurationFactoryBean freeMarkerConfigurationFactoryBean() throws IOException {
        FreeMarkerConfigurationFactoryBean bean = new FreeMarkerConfigurationFactoryBean();
        bean.setTemplateLoaderPath(templateLoaderPath);
        // 设置页面名称和路径
        Map<String, String> nameMapping = new HashMap<>();
        nameMapping.put("goods.ftl", "goods.html");
        bean.setFreemarkerVariables(Collections.singletonMap("nameMapping", nameMapping));
        Properties settings = new Properties();
        settings.setProperty(freemarker.template.Configuration.TEMPLATE_UPDATE_DELAY_KEY, "5000");
        // 设置FreeMarker相关设置
        bean.setFreemarkerSettings(settings);
        return bean;
    }

    @Bean
    public FreeMarkerConfigurer freeMarkerConfigurer(FreeMarkerConfigurationFactoryBean bean) throws IOException {
        FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
        configurer.setConfiguration(bean.getObject());
        configurer.setDefaultEncoding("UTF-8");
        configurer.setPreferFileSystemAccess(false);
        Map<String, String> mappings = new HashMap<>();
        mappings.put("*.ftl", "*.html");
        configurer.setFreemarkerMappings(mappings);
        configurer.setFreeMarkerVariables(Collections.singletonMap("STATIC_FILE_LOADER",
        staticFileLoaderPath));
        return configurer;
    }

}
  1. 构建Java模板引擎工具类

构建一个工具类,用于将Java对象转化为Map,并结合相应的模板文件生成静态的HTML文件。代码如下:

@Service
public class FreeMarkerService {

    @Autowired
    private Configuration configuration;

    public void toHtml(String templateName, String staticFileName, Object data) throws Exception {
        // 获取模板
        Template template = configuration.getTemplate(templateName);
        // 设置静态化文件路径
        String path = "./static/" + staticFileName;
        // 获取输出流
        FileWriter fileWriter = new FileWriter(path);
        // 渲染模板生成静态文件
        template.process(data, fileWriter);
        // 关闭输出流
        fileWriter.close();
    }

    public Map<String, Object> objectToMap(Object obj) throws Exception {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<>();
        BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor property : propertyDescriptors) {
            String key = property.getName();

            if (key.compareToIgnoreCase("class") == 0) {
                continue;
            }
            Method getter = property.getReadMethod();
            Object value = getter == null ? null : getter.invoke(obj);
            map.put(key, value);
        }
        return map;
    }

    /**
     * 利用对象数据生成静态页面
     * @param templateName
     * @param staticFileName
     * @param obj
     * @throws Exception
     */
    public void toHtmlFromObject(String templateName, String staticFileName, Object obj) throws Exception {
        Map<String, Object> map = objectToMap(obj);
        toHtml(templateName, staticFileName, map);
    }

}
  1. 构建测试类

在测试类中使用方法 toHtmlFromObject:将数据模型填充到模板中生成完整的HTML页面,并将HTML 页面中的占位符等内容替换成相应的数据。代码如下:

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

    @Autowired
    private FreeMarkerService freeMarkerService;

    /**
     * 商品详情页面示例
     */
    @Test
    public void goodsTest() throws Exception {
        Goods goods = new Goods();
        goods.setName("iPhone 13");
        goods.setDescription("最新款 iPhone");
        goods.setPrice(new BigDecimal(9999));
        goods.setSales(0);
        // 模拟访问详情页,将数据转成静态文件
        freeMarkerService.toHtmlFromObject("goods.ftl", "iphone13_detail.html", goods);
    }

}
  1. 代码解析

在以上示例中,离线化实现过程核心是由 FreeMarker 实现模板渲染生成 HTML 页面,然后将生成的页面通过 Java IO 流输出到指定文件。具体代码解析如下:

FreeMarker 配置

FreeMarker 通过 Configuration(配置类)对模板引擎的配置进行初始化操作,将配置类作为参数进行构造,以便 FreeMarker 可以读取配置类中的各项参数进行初始化。示例中配置模板、静态文件存储路径,开启自动检测页面更新功能,将数据模型的变量名映射到文件名称的映射关系保存在 FreeMarker 配置的 freemarkerVariables 属性中,便于其他方法调用使用。

工具类 FreeMarkerService

FreeMarkerService 类是生成静态页面的核心类,它是将数据模型插入到 HTML 页面模板中、渲染对象存放于键值对 Map 中,并将生成的页面保存到指定的文件中。示例中主要通过 toHtml 方法来实现,它接受三个参数:模板名称、存储路径、数据模型,其中模板名称和存储路径的参数类型都是字符串类型。处理过程中,首先通过 Configuration 对模板进行初始化,然后使用 Template 实例加载模板,将渲染后的 HTML 页面生成文件大输出到指定路径, 最后关闭流。

toHtml 方法中,调用了 FreeMarker 的 process 方法,将配置类(即 Configuration)和数据模型传入,生成目标 HTML 页面内容并存入指定的输出流对应的文件中。

objectToMap 将对象转化成 Map 格式的数据,便于 FreeMarker 将对象数据模型中的数据解析出来填充到模板中。返回的 Map 对象中,键是数据变量名,值是变量值。

toHtmlFromObject 方法是生成静态页面的主方法,首先将 java 对象转成 Map 格式,然后以转换好的数据模型填充到模板中。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java Freemarker页面静态化实例详解 - Python技术站

(0)
上一篇 2023年6月15日
下一篇 2023年6月15日

相关文章

  • 浅谈JAVA8给我带了什么——流的概念和收集器

    浅谈JAVA8给我带了什么——流的概念和收集器 流的概念 流指的是Java 8中引入的一种新的数据处理方式,它可以被抽象为一个支持并行处理的元素序列。在流中,数据源本身可以是一个数组、集合、I/O channel、产生元素序列的generator function等。与集合不同的是,流本身并不储存数据,它只是对数据源中数据的一种延迟计算视图,数据源中的元素能…

    Java 2023年5月19日
    00
  • Java的Struts框架报错“BaseException”的原因与解决办法

    当使用Java的Struts框架时,可能会遇到“BaseException”错误。这个错误通常由以下原因之一起: 配置错误:如果配置文件中没有正确配置Action,则可能会出现此。在这种情况下,需要检查配置文件以解决此问题。 代码错误:如果编写的代码中存在错误,则可能会出现此。在这种情况下,需要检查代码以解决此问题。 以下是两个实例: 例 1 如果配置文件中…

    Java 2023年5月5日
    00
  • java中实体类转Json的2种方法

    下面来详细讲解Java中实体类转JSON的2种方法的攻略。 1. 使用Gson库进行实体类转JSON Gson是Google开发的可以用来将Java对象转换成JSON字符串,也可以将JSON字符串转换成Java对象的库。下面是一个使用Gson库进行转换的示例代码: import com.google.gson.Gson; public class Perso…

    Java 2023年5月20日
    00
  • 10个Java程序员熟悉的面向对象设计原则

    为了让Java程序员编写高质量的面向对象代码,需要了解并应用常见的面向对象设计原则。下面介绍的是10个Java程序员熟悉的面向对象设计原则的完整攻略。 1. 单一职责原则(SRP) 单一职责原则规定一个类只有一个职责,即一个类只负责实现单一的功能。如果一个类承担了多个职责,则这个类变得难以修改,测试和复用,会导致代码的混乱和不可维护性。 示例说明:例如,假设…

    Java 2023年5月26日
    00
  • Java编程中使用lambda表达式的奇技淫巧

    Java编程中使用lambda表达式的奇技淫巧 Lambda表达式是自Java 8引入的一项重要特性,它使得Java编程变得更加灵活和便捷。在本篇文章中,我们将介绍一些使用Lambda表达式的奇技淫巧,在实际编程中提高效率和代码质量。 1. Lambda表达式与函数式接口 Lambda表达式实际上就是一段可执行的代码块,它可以作为一种新的语法形式,用来简化接…

    Java 2023年5月26日
    00
  • java~springboot~ibatis数组in查询的实现方法

    下面我给您详细讲解Java SpringBoot集成iBatis实现数组IN查询的方法。 什么是iBatis iBatis是一款持久层框架,其通过提供的半自动ORM工具简化了数据库操作,使得开发者能够更加关注业务逻辑的实现。 数组IN查询的实现方式 当我们需要查询某个字段的值一次匹配多个值时,便需要使用数组IN查询。iBatis支持两种方式实现数组IN查询:…

    Java 2023年5月20日
    00
  • Java利用HttpClient模拟POST表单操作应用及注意事项

    Java利用HttpClient模拟POST表单操作应用及注意事项 前言 在实现Java程序中模拟POST表单操作时,HttpClient是一个非常常用的工具。本文将介绍HttpClient的基本使用方法,以及在模拟POST表单操作时需要注意的一些细节。 HttpClient是什么 HttpClient是一个基于Http协议的开源库,可以通过HttpClie…

    Java 2023年5月19日
    00
  • Spring Security中使用authorizeRequests遇到的问题小结

    (注:以下是针对题目中“Spring Security中使用authorizeRequests遇到的问题小结”的完整攻略) 问题描述 在使用Spring Security过程中,我们可能会使用到 .authorizeRequests() 方法,它用于配置访问控制,但在配置过程中可能会出现一些问题。 问题分析 常见的 .authorizeRequests() …

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部