freemark从数据库读取模板且实时更新


本例子只是简单的实现,如有问题请指出。
转载请注明出处:https://blog.csdn.net/u014508380/article/details/88226855

freemark加载模板

框架提供的读取模板的方式

1.void setDirectoryForTemplateLoading(File dir);//从磁盘的文件系统上的目录加载模板
2.void setClassForTemplateLoading(Class cl, String prefix);//从类路径下加载模板
3.void setServletContextForTemplateLoading(Object servletContext, String path);//从Web应用目录开始加载模板

从多个位置加载模板

如果需要从多个位置加载模板,那就不得不为每个位置都实例化模板加载器对象, 将它们包装到一个称为 MultiTemplateLoader 的特殊模板加载器, 最终将这个加载器传递给 Configuration 对象的 setTemplateLoader(TemplateLoader loader)方法。 下面给出一个使用类加载器从两个不同位置加载模板的示例:

FileTemplateLoader ftl1 = new FileTemplateLoader(new File("/tmp/templates"));
FileTemplateLoader ftl2 = new FileTemplateLoader(new File("/usr/data/templates"));
ClassTemplateLoader ctl = new ClassTemplateLoader(getClass(), "");
TemplateLoader[] loaders = new TemplateLoader[] { ftl1, ftl2, ctl };
MultiTemplateLoader mtl = new MultiTemplateLoader(loaders);

cfg.setTemplateLoader(mtl);

自定义加载方式

因为内建的类加载器无法从数据库中读取模板,于是编写自己的类加载器, 这个类需要实现 freemarker.cache.TemplateLoader 接口, 然后将它传递给 Configuration 对象的 setTemplateLoader(TemplateLoader loader)方法。
1、DbTemplateLoader:自定义的模板加载器
2、DbTemplateSource:模板加载的资源类
3、FreemarkerTransformEngine:模板的配置类
4、FreemarkController:调用的示例类

DbTemplateLoader

public class DbTemplateLoader implements TemplateLoader {
    private FreemarkRecordMapper mapper;

    DbTemplateLoader(FreemarkRecordMapper mapper) {
        this.mapper = mapper;
    }

    @Override
    public Object findTemplateSource(String name) {
        int lastUnderscore = name.lastIndexOf('_');
        if (lastUnderscore != -1) {
            name = name.substring(0, lastUnderscore);
        }
        return new DbTemplateSource(mapper, name);
    }

    /**
     * 最后修改的版本,用于判断是否直接读取缓存
     * @param templateSource
     * @return
     */
    @Override
    public long getLastModified(Object templateSource) {
        return ((DbTemplateSource) templateSource).lastModified();
    }

    @Override
    public Reader getReader(Object templateSource, String encoding) throws IOException {
        return new InputStreamReader(
                ((DbTemplateSource) templateSource).getInputStream(),
                encoding);
    }

    @Override
    public void closeTemplateSource(Object templateSource) throws IOException {
        ((DbTemplateSource) templateSource).close();
    }
}

DbTemplateSource

@Slf4j
public class DbTemplateSource {
    private FreemarkRecordMapper mapper;
    private FreemarkRecord freemarkRecord;
    private InputStream inputStream;

    DbTemplateSource(FreemarkRecordMapper mapper, String name) {
        this.mapper = mapper;
        this.freemarkRecord = FreemarkRecord.builder().recordCode(name).build();
    }

    long lastModified() {
        if (Objects.isNull(mapper)) {
            return 0;
        }
        //优化建议:可以设置缓存,库表修改后更新缓存
        FreemarkRecord freemarkRecordTemp = mapper.selectOne(freemarkRecord);
        if (Objects.isNull(freemarkRecordTemp)) {
            return 0;
        }
        return freemarkRecordTemp.getVersion();
    }

    InputStream getInputStream() {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                log.info("异常={}", e);
            }
        }
        if (Objects.isNull(mapper)) {
            return new StringInputStream("");
        }
        FreemarkRecord freemarkRecordTemp = mapper.selectOne(freemarkRecord);
        String jsonData = "";
        if (Objects.nonNull(freemarkRecordTemp)) {
            jsonData = freemarkRecordTemp.getJsonResource();
        }
        inputStream = new StringInputStream(jsonData);
        return inputStream;
    }

    void close() throws IOException {
        try {
            if (inputStream != null) {
                inputStream.close();
            }
        } finally {
            inputStream = null;
        }
    }

    /**
     * 比较两个templateSource是否相同,用于判断是否直接读取缓存
     */
    @Override
    public boolean equals(Object o) {
        if (o instanceof DbTemplateSource) {
            return Objects.equals(freemarkRecord.getRecordCode(), ((DbTemplateSource) o).getFreemarkRecord().getRecordCode());
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return freemarkRecord.getRecordCode().hashCode();
    }


    private FreemarkRecord getFreemarkRecord() {
        return freemarkRecord;
    }

}

FreemarkerTransformEngine

@Slf4j
@Component
public class FreemarkerTransformEngine implements InitializingBean {
    @Resource
    private FreemarkRecordMapper mapper;

    private Configuration cfg;

    public FreemarkerTransformEngine() {
    }

    private void initConfiguration() {
        cfg = new Configuration(Configuration.VERSION_2_3_23);
        cfg.setDefaultEncoding("UTF-8");
        cfg.setLocale(Locale.CHINESE);
        cfg.setNumberFormat("#");
        extendCfg();
    }

    /**
     * 设置template加载方式
     */
    private void extendCfg() {
        TemplateLoader[] loaders = new TemplateLoader[]{new DbTemplateLoader(mapper)};
        MultiTemplateLoader mtl = new MultiTemplateLoader(loaders);
        cfg.setTemplateLoader(mtl);
    }

    public String transform2String(String templateName, Map<String, Object> input) {
        Template template = this.getTemplate(templateName);
        StringWriter stringWriter = new StringWriter();
        if (Objects.isNull(template)) {
            return "";
        }
        try {
            template.process(input, stringWriter);
        } catch (TemplateException | IOException e) {
            log.error(e.getMessage(), e);
        }
        return stringWriter.toString();
    }

    private Template getTemplate(String templateName) {
        try {
            return cfg.getTemplate(templateName);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    @Override
    public void afterPropertiesSet() {
        this.initConfiguration();
    }

}

FreemarkController

@Slf4j
@RestController
public class FreemarkController {
    @Autowired
    private FreemarkerTransformEngine engine;

    @RequestMapping("/transform2String")
    public String transform2String(String templateName) {
        HashMap<String, Object> input = Maps.newHashMap();
        input.put("phone", "13644441111");
        return engine.transform2String(templateName, input);
    }
}

通过http://localhost:8081/transform2String?templateName=test可调用,获取响应的数据;
templateName:表示数据库里模板的编码【唯一标识】
响应的数据例子:

	{
	    "name": "",
	    "sign": "",
	    "key": "",
	    "payload": {
	        "phone": "13644441111",
	        "idCard": "",
	        "name": "",
	        "ip": "",
	        "deviceId": "",
	        "productCode": ""
	    }
	}

FreemarkRecord对应的数据库脚本

说明:只要在修改了json_resource,同时修改version字段的值【可累加】,则前端调用接口后,返回的json_resource即是修改后的数据。

create table freemark_record
(
  id            bigint auto_increment
    primary key,
  record_code   varchar(50) default ''   not null
  comment '记录的编码',
  json_resource varchar(1000) default '' not null
  comment 'json格式的数据',
  version       int default '0'          null
  comment '版本',
  create_time   datetime                 null
  comment '创建时间'
)
  comment 'freemark_json记录表';
  
#  数据例子:
INSERT INTO zxytest.freemark_record (id, record_code, json_resource, version, create_time) VALUES (1, 'test', '{
 "name":"${name!}",
  "sign": "${sign!}",
  "key": "${key!}",
  "payload":{
      "phone": "${phone!}",
      "idCard": "${idCard!}",
      "name": "${name!}",
      "ip": "${ip!}",
      "deviceId": "${deviceId!}",
      "productCode": "${productCode!}"
  }
}', 2, '2019-03-04 01:56:04');
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值