对freemarker输出的模板进行加工

     这次主要是因为后期需要在项目里对js和css添加版本号,防止一些缓存的问题。页面比较多,就不能每个页面引用的js和css添加版本号了,那样太累,对后期的更新也不方便。

     你可能专门做了js和css的模板文件,其他页面引入就好了,但是每个页面也有其自己的资源文件,要是加在页面,这个文件你手动换了,另外一个页面忘记了,也都是麻烦。

      你也可以增加FreeMarkerView,在里边增加一个自定义的类似${version}的东西,但在每个页面不还得xxx.js?v=${version}吗?太麻烦。

      所以我就想,能不能把freemarker获取到的模板文件字符串的时候,用正则给给它加上,这样维护起来也方便。

      由于项目时springboot,就拿他当例子搞了。如果你用的spring,直接配置xml会更简单。

      直接贴代码了:

     


首先继承TemplateLoaer类,这个类里边有个getReader方法,是获取模板文件的,我们可以在这里进行加工。

package com.xyauto.qa.core.processor;

import com.xyauto.qa.util.SpringIocUtil;
import com.xyauto.qa.util.TemplateUtils;
import freemarker.cache.TemplateLoader;
import org.apache.commons.io.IOUtils;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;


/**
 * Created by shiqm on 2017-06-30.
 */
public class ResourceTemplateLoader implements TemplateLoader {

    private final TemplateLoader delegate;

    public ResourceTemplateLoader(TemplateLoader delegate) {
        this.delegate = delegate;
    }

    @Override
    public Object findTemplateSource(String s) throws IOException {
        return delegate.findTemplateSource(s);
    }

    @Override
    public long getLastModified(Object o) {
        return delegate.getLastModified(o);
    }

    @Override
    public Reader getReader(Object o, String s) throws IOException {
        Reader reader = delegate.getReader(o, s);
        TemplateUtils templateUtils= (TemplateUtils) SpringIocUtil.getBean("templateUtils");
        String content= IOUtils.toString(reader);
        content = templateUtils.getScriptSrcList(content);
        content = templateUtils.getLinkHrefList(content);
        return new StringReader(content);
    }




    @Override
    public void closeTemplateSource(Object o) throws IOException {
        delegate.closeTemplateSource(o);
    }
}

上边注意需要引入一个工具类,主要是用它把reader转成字符串,当然你也可以根据实现自己写,但要注意原格式必须正确,回车空格不能少。不然浏览器不会有问题,但是你看页面源代码的source肯定是乱的。我比较懒,就直接用工具类走了。

  <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.5</version>
  </dependency>


下一步就将这个类替换freemarker本身的Loader类,在Application运行文件里添加

import freemarker.template.Configuration;

    @Bean
    public CommandLineRunner customFreemarkerTemplateLoader(Configuration configuration) {
        return new CommandLineRunner() {
            @Override
            public void run(String... strings) throws Exception {
                ResourceTemplateLoader resourceTemplateLoader = new ResourceTemplateLoader(configuration.getTemplateLoader());
                configuration.setTemplateLoader(resourceTemplateLoader);
            }
        };
    }

看代码就看出来的,从Configuration中取出默认的来,set进去替换就好了。



之后这里贴上正则的方法,有需要的拿去,自己根据需求写也可以。这个只是个思路,做其他需求也可以往这考虑。当然这里用做给资源文件加版本号也有弊端,就是更新的时候会整体更新。没有更改的也会重新加载。因为改的急,我就先这么动了代码。


 public String getScriptSrcList(String content) {
        Map map = new HashMap();
        Pattern p_script = Pattern.compile("(?<=script)(.*?)(?=></script>|/>)");
        Matcher m_script = p_script.matcher(content);
        while (m_script.find()) {
            String temp = m_script.group();
            Pattern p_src = Pattern.compile("(?<=src=\")(.*?)(?=\")");
            Matcher m_src = p_src.matcher(temp);
            while (m_src.find()) {
                String tempSrc = m_src.group();
                if (tempSrc.indexOf("?v=") > -1) {
                    continue;
                }
                if (!StringUtils.isEmpty(map.get(tempSrc))) {
                    continue;
                }
                content = content.replace(tempSrc, tempSrc + qcdqcdnStatic.getResourceVersion());
                map.put(tempSrc, "1");
            }
        }
        map.clear();
        return content;
    }

    public String getLinkHrefList(String content) {
        Map map = new HashMap();
        Pattern p_script = Pattern.compile("(?<=link)(.*?)(?=></link>|/>|>)");
        Matcher m_script = p_script.matcher(content);
        while (m_script.find()) {
            String temp = m_script.group();
            Pattern p_src = Pattern.compile("(?<=href=\")(.*?)(?=\")");
            Matcher m_src = p_src.matcher(temp);
            while (m_src.find()) {
                String tempSrc = m_src.group();
                if (tempSrc.indexOf("?v=") > -1) {
                    continue;
                }
                if (!StringUtils.isEmpty(map.get(tempSrc))) {
                    continue;
                }
                content = content.replace(tempSrc, tempSrc + qcdqcdnStatic.getResourceVersion());
                map.put(tempSrc, "1");
            }
        }
        map.clear();
        return content;
    }


replace替换那里,我是把版本号控制放在配置文件里的,这个根据自己吧,你直接写也没人管你,不过还是希望透明一些,能让同事看懂。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值