在一个大网站里,有很多子域名对应到很多子系统,这些子系统由不同的团队负责,如何保证整个网站的风格一致性(最基本的页头、页尾必须一致),这个时候就得提供一份统一的页头、页尾以及公共的JS、css等内容,但如果是直接给源代码(ftl/js/css)的形式,对于后期的升级维护必然增加不必要的麻烦,必须得只有一个地方维护这个代码。
freemarker提供了远程模板加载的功能,在各个业务方里就像使用本地的模板一样使用远程的统一的模板代码。
RemoteTemplateLoader是我们实现的freemarker的URLTemplateLoader抽象类的远程模板加载类。代码如下:
import freemarker.cache.URLTemplateLoader; import org.apache.commons.lang.StringUtils; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.Arrays; import java.util.List; /** * 自定义远程模板加载器,用来加载远程机器上存放的模板文件.HTTP * * @author Administrator */ public class RemoteTemplateLoader extends URLTemplateLoader { // 远程模板文件的存储路径(目录) private String remotePath; private List<String> includePaths; private String paths; 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 public Object findTemplateSource(String name) throws IOException { if (this.includePaths != null && this.includePaths.contains(name)) { return super.findTemplateSource(name); } return null; } @Override protected URL getURL(String name) { // name = name.replace("_zh", ""); String fullPath = this.remotePath + name; if ((this.remotePath.equals("/")) && (!isSchemeless(fullPath))) { return null; } URL url = null; try { url = new URL(fullPath); } catch (MalformedURLException e) { e.printStackTrace(); } 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; } public void setRemotePath(String remotePath) { this.remotePath = remotePath; } public void setPaths(String paths) { this.paths = paths; if (StringUtils.isNotEmpty(this.paths)) { String[] s = this.paths.split(";"); this.includePaths = Arrays.asList(s); } } }
<bean id="remoteTemplateLoader" class="com.pinhuba.common.web.freemarker.RemoteTemplateLoader"> <constructor-arg name="remotePath" value="http://static.pinhuba.com" /> <property name="paths" value="tpl/footer.html;tpl/header.html;tpl/wap_header.html;tpl/wap_footer.html;tpl/wap_nav.html" /> </bean> <util:list id="preTemplateLoaders" list-class="java.util.ArrayList" value-type="com.pinhuba.common.web.freemarker.RemoteTemplateLoader"> <ref bean="remoteTemplateLoader" /> </util:list> <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <!--获取标签配置--> <property name="freemarkerVariables" value="#{propertyUtils.getBeanMap('directive.')}"/> <property name="templateLoaderPath" value=""/> <property name="postTemplateLoaders" ref="preTemplateLoaders" /> <property name="freemarkerSettings"> <props> <prop key="tag_syntax">auto_detect</prop> <prop key="template_update_delay">5</prop> <prop key="defaultEncoding">UTF-8</prop> <prop key="url_escaping_charset">UTF-8</prop> <prop key="locale">zh_CN</prop> <prop key="boolean_format">true,false</prop> <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop> <prop key="date_format">yyyy-MM-dd</prop> <prop key="time_format">HH:mm:ss</prop> <prop key="number_format">0.######</prop> <prop key="whitespace_stripping">true</prop> <prop key="auto_import">/WEB-INF/ftl/spring.ftl as s</prop> </props> </property> </bean>
[#include "/tpl/header.html"/]
这个上面的url中是在RemoteTemplateLoader的XML的参数里已经进行了配置,所以跟使用本地的模板是一样的。
发表评论(对文章涉及的知识点还有疑问,可以在这里留言,老高看到后会及时回复的。)