Thymeleaf 3.0教程:15 更多的配置信息(一)
15.1 模板解析器
对于我们的虚拟杂货店,我们选择了一个名为ServletContextTemplateResolver的ITemplateResolver实现,它允许我们从Servlet上下文中获取模板作为资源。
Thymeleaf除了让我们能够通过实现ITemplateResolver来创建自己的模板解析器之外,还包括四个现成的实现:
org.thymeleaf.templateresolver.ClassLoaderTemplateResolver,它将模板解析为类加载器资源,如:
return Thread.currentThread().getContextClassLoader().getResourceAsStream(template);
org.thymeleaf.templateresolver.FileTemplateResolver, 它将模板解析为文件系统中的文件,例如:
return new FileInputStream(new File(template));
org.thymeleaf.templateresolver.UrlTemplateResolver, 它将模板解析为URL,例如:
return (new URL(template)).openStream();
org.thymeleaf.templateresolver.StringTemplateResolver, 它将模板直接解析为被指定为模板的字符串(或者模板名称,在本例中,它显然不仅仅是一个名称):
return new StringReader(templateName);
ITemplateResolver的所有预绑定实现都允许相同的配置参数集,包括:
前缀和后缀(如前所述):
templateResolver.setPrefix("/WEB-INF/templates/"); templateResolver.setSuffix(".html");
还可以使用模板别名,如果suffix/prefix和alias都存在,alias将应用于suffix/prefix之前:
templateResolver.addTemplateAlias("adminHome","profiles/admin/home"); templateResolver.setTemplateAliases(aliasesMap);
读取模板时要应用的编码:
templateResolver.setEncoding("UTF-8");
要使用的模板模式:
// Default is HTML templateResolver.setTemplateMode("XML");
模板缓存的默认模式,以及定义特定模板是否可缓存的模式:
// Default is true templateResolver.setCacheable(false); templateResolver.getCacheablePatternSpec().addPattern("/users/*");
源自此模板解析器的解析模板缓存条目的TTL(毫秒)。如果未设置,从缓存中删除条目的唯一方法是超过缓存的最大大小(最旧的条目将被删除)。
// Default is no TTL (only cache size exceeded would remove entries) templateResolver.setCacheTTLMs(60000L);
Thymeleaf+ Spring集成包提供了一个SpringsresourceTemplateResolver实现,它使用所有Spring基础结构来访问和读取应用程序中的资源,这是支持Spring的应用程序中推荐的实现。
链接模板解析器
此外,模板引擎可以指定几个模板解析器,在这种情况下,可以在它们之间建立模板解析的顺序,这样,如果第一个无法解析模板,就会尝试第二个,依此类推:
ClassLoaderTemplateResolver classLoaderTemplateResolver = new ClassLoaderTemplateResolver(); classLoaderTemplateResolver.setOrder(Integer.valueOf(1)); ServletContextTemplateResolver servletContextTemplateResolver = new ServletContextTemplateResolver(servletContext); servletContextTemplateResolver.setOrder(Integer.valueOf(2)); templateEngine.addTemplateResolver(classLoaderTemplateResolver); templateEngine.addTemplateResolver(servletContextTemplateResolver);
当应用多个模板解析器时,建议为每个模板解析器指定模式,以便Thymeleaf可以快速丢弃那些不打算解析模板的模板解析器,从而提高性能。这样做不是一个要求,而是一个建议:
ClassLoaderTemplateResolver classLoaderTemplateResolver = new ClassLoaderTemplateResolver(); classLoaderTemplateResolver.setOrder(Integer.valueOf(1)); // This classloader will not be even asked for any templates not matching these patterns classLoaderTemplateResolver.getResolvablePatternSpec().addPattern("/layout/*.html"); classLoaderTemplateResolver.getResolvablePatternSpec().addPattern("/menu/*.html"); ServletContextTemplateResolver servletContextTemplateResolver = new ServletContextTemplateResolver(servletContext); servletContextTemplateResolver.setOrder(Integer.valueOf(2));
如果没有指定这些可解析模式,我们将依赖于我们正在使用的每个ITemplateResolver实现的特定功能。请注意,并非所有的实现都能够在解析之前确定模板的存在,因此总是可以将模板视为可解析的,并打破解析链(不允许其他解析器检查相同的模板),但是无法读取真正的资源。
核心Thymeleaf中包含的所有ITemplateResolver实现都包含一种机制,允许我们在考虑资源是否可解析之前,让解析器真正检查资源是否存在。这是检查存在标志,其工作方式如下:
ClassLoaderTemplateResolver classLoaderTemplateResolver = new ClassLoaderTemplateResolver(); classLoaderTemplateResolver.setOrder(Integer.valueOf(1)); classLoaderTempalteResolver.setCheckExistence(true);
该检查存在标志强制解析器在解析阶段执行资源存在的实际检查(如果存在检查返回false,则调用链中的以下解析器)。虽然这在每种情况下听起来都不错,但在大多数情况下,这意味着对资源本身的双重访问(一次用于检查是否存在,另一次用于读取),并且在某些情况下可能是一个性能问题,例如基于远程网址的模板资源,这是一个潜在的性能问题,无论如何都可能通过模板缓存的使用而大大减轻(在这种情况下,模板只能在第一次访问时解决)。