FreeMarker通过URL的形式加载远程主机上的模板文件

一、添加FreeMarker依赖

我这边使用的是Spring Boot的Maven项目,所以先在maven中添加依赖

        <!--引入freeMarker依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

二、控制器的导出方法

    @RequestMapping("exportWord")
    @ResponseBody
    public void exportWord(HttpServletResponse response){
        // 获取模板所需的项目数据
        Map<String, Object> dataMap = new HashMap<>();
//        dataMap.forEach((e,f)->{
//            System.out.println(e+":"+f);
//        });
        Writer out = null;
        try {
            // 清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename="+new String( ("test.doc").getBytes("gb2312"), "ISO8859-1" ) );
            response.setContentType("application/octet-stream");

            // 配置FreeMarker的版本号及编码格式
            Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);
            configuration.setDefaultEncoding("UTF-8");
            // 远程模板所在位置
            RemoteTemplateLoader templateLoader = new RemoteTemplateLoader("你的URL路径");
            configuration.setTemplateLoader(templateLoader);
            // 加载模版文件
            Template template = configuration.getTemplate("test.ftl","UTF-8");
            // 输出文件
            BufferedOutputStream bus = new BufferedOutputStream(response.getOutputStream());
            out = new BufferedWriter(new OutputStreamWriter(bus,"UTF-8"));
            template.process(dataMap, out);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != out) {
                    out.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }

使用FreeMarker的方式不外乎是获取到模板+数据,两两绑定,最后输出结果。上述是在Spring Boot的控制器中使用FreeMarker下载Word文档的写法,与大多数导出方式类似。不过,今天的主题是如何使用URL的形式加载远程主机上的模板,也就是确定了模板的URL路径,如何加载到项目中

三、编写URL远程下载的加载器

FreeMarker本身并没有提供对应的URL远程加载模板的加载器,官网上也只是很简单地说了一下

根据FreeMarker的加载机制,那我们继承URLTemplateLoader加载类,再实现它的getURL()方法,稍微修改一下路径。

编写一个我们自己的类RemoteTemplateLoader.class

package com.mine.risk.freeMarker;

import freemarker.cache.URLTemplateLoader;

import java.net.MalformedURLException;
import java.net.URL;

/**
 * 远程URL地址的方式实现模板加载
 * @author spirit
 * @version 1.0
 * @date 2019-09-10 11:09
 */
public class RemoteTemplateLoader extends URLTemplateLoader {
    /** 远程模板文件的存储路径(目录)*/
    private String remotePath;

    public RemoteTemplateLoader(String remotePath) {
        if (remotePath == null) {
            throw new IllegalArgumentException("remotePath is null");
        }
        this.remotePath = canonicalizePrefix(remotePath);
        if (this.remotePath.indexOf('/') == 0) {
            this.remotePath = this.remotePath.substring(this.remotePath.indexOf('/') + 1);
        }
    }

    @Override
    protected URL getURL(String name) {
        String fullPath = this.remotePath + name;
        fullPath = fullPath.replace("_zh", "").replace("_CN","");
        if ((this.remotePath.equals("/")) && (!isSchemeLess(fullPath))) {
            return null;
        }
        URL url = null;
        try {
            url = new URL(fullPath);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        System.out.println("url==="+url);
        return url;
    }

    private static boolean isSchemeLess(String fullPath) {
        int i = 0;
        int ln = fullPath.length();

        if ((i < ln) && (fullPath.charAt(i) == '/')){
            i++;
        }

        while (i < ln) {
            char c = fullPath.charAt(i);
            if (c == '/'){
                return true;
            }
            if (c == ':'){
                return false;
            }
            i++;
        }
        return true;
    }

}

最后,大家有什么不懂的或者其他需要交流的内容,也可以进入我的QQ讨论群一起讨论:654331206

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值