Freemarker中如何读取jar中的template且支持原生的include引入其他模板

写这篇文章主要是考虑到如下问题会困扰大家

  1. java.io.FileNotFoundException: Template xxx.ftl not found.
  2. 如何让模板中支持原生的<#include “common.ftl”>
  3. 如何在编辑ftl文件中变量的时候能够有有效的提示(此处使用的是idea)

解决方案

首先,看下TemplateLoader实现类有哪些
Freemarker中如何读取jar中的template且支持原生的include引入其他模板_第1张图片
对于打jar包后的读取ftl文件需要通过流读取文件或者通过URL
此处就简单的以StringTemplateLoader为例简单介绍,直接贴代码演示

    /**
     * 初始化include模板
     *
     * @param templateContent
     * @param stringTemplateLoader
     */
    public static void initCommonTemplate(String templateContent, StringTemplateLoader stringTemplateLoader) {
     
        // 按指定模式在字符串查找
        String pattern = "(?<=<#include\\s\")(.*?)(?=\"\\s*>)";
        // 创建 Pattern 对象
        Pattern r = Pattern.compile(pattern);
        // 现在创建 matcher 对象
        Matcher m = r.matcher(templateContent);
        while (m.find()) {
     
            String childTemplateName = "";
            String group = m.group();
            if (group.startsWith("/")) {
     
                childTemplateName = group.substring(1);
            } else {
     
                childTemplateName = group;
            }
            stringTemplateLoader.putTemplate(childTemplateName, ResourceHelper.getString(group));
        }
    }

    public static void main(String[] args) throws Exception{
     

        //region 初始化模板过程
        Configuration ftlConifg = new Configuration(Configuration.VERSION_2_3_29);
        String path = "a.ftl";
        //获取文件内容
        InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
        String content = new BufferedReader(new InputStreamReader(resourceAsStream, StandardCharsets.UTF_8))
                .lines()
                .collect(Collectors.joining("\n"));

        //将其填充到stringTemplateLoader中
        StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
        stringTemplateLoader.putTemplate(path,content);
        //填充content中include的模板
        initCommonTemplate(content,stringTemplateLoader);
        ftlConifg.setTemplateLoader(stringTemplateLoader);
        //endregion

        //region 获取填充数据后的模板
        //读取模板
        Template template = ftlConifg.getTemplate(path, StandardCharsets.UTF_8.toString());

        //填充数据
        Object data = new Object();
        var out = new StringWriter();
        template.process(Map.of("item", data), out);
        String result  = out.toString();
        //endregion

    }

此外补充一点(如何在编辑ftl文件中变量的时候能够有有效的提示)
在ftl文件开头加上如下内容,编辑的时候会有代码提示

<#-- @ftlvariable name="item" type="class路径" -->

你可能感兴趣的:(javaweb)