对freemarker输出的模板进行加工

来源:互联网 发布:artrage中文版 mac 编辑:程序博客网 时间:2024/05/16 18:53

     这次主要是因为后期需要在项目里对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替换那里,我是把版本号控制放在配置文件里的,这个根据自己吧,你直接写也没人管你,不过还是希望透明一些,能让同事看懂。





原创粉丝点击