Thymeleaf 教程

模板解析器配置

对于我们的 Good Thymes 虚拟杂货店,我们选择了一个名为 ServletContextTemplateResolver 的 ITemplateResolver 实现,它允许我们从 ServletContext 获得模板资源。

除了让我们通过实现 ITemplateResolver 接口来创建自己的模板解析器外,Thymeleaf 还包括四个开箱即用的内置实现:

(1)ClassLoaderTemplateResolver

org.thymeleaf.templateresolver.ClassLoaderTemplateResolver,它将模板解析为 classloader 资源,例如:

return Thread.currentThread().getContextClassLoader().getResourceAsStream(template);

(2)FileTemplateResolver

org.thymeleaf.templateresolver.FileTemplateResolver,它将模板解析为来自文件系统的文件,例如:

return new FileInputStream(new File(template));

(3)UrlTemplateResolver

org.thymeleaf.templateresolver.UrlTemplateResolver,它将模板解析为 URL(甚至是非本地的)资源,例如:

return (new URL(template)).openStream();

(4)StringTemplateResolver

org.thymeleaf.templateresolver.StringTemplateResolver,它将模板直接解析为被指定为模板的字符串(或模板名称,在这种情况下,显然远远超过了单纯的名称)。例如:

return new StringReader(templateName);

在 Thymeleaf 中,ITemplateResolver 接口的所有内置实现都有相同的配置参数集,其中配置参数包括:

  • 配置前缀和后缀

templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
  • 配置模板别名,允许使用模板的非真实文件名称,而是使用别名。如果后缀/前缀和别名都存在,别名将在前缀/后缀之前被应用:

templateResolver.addTemplateAlias("adminHome","profiles/admin/home");
templateResolver.setTemplateAliases(aliasesMap);
  • 读取模板时要应用的编码:

templateResolver.setCharacterEncoding("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 集成包提供了一个 SpringResourceTemplateResolver 实现,它使用所有 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 实现的特定功能。注意,并不是所有的实现都能够在解析之前确定模板的存在,因此可能总是认为模板是可解析的,并中断解析链(不允许其他解析器检查相同的模板),但随后无法读取实际资源。

checkExistence 标志强制解析器在解析阶段对资源的存在进行真正的检查(如果存在性检查返回错误,就让链上的后续解析器被调用)。虽然这在每种情况下都听起来不错,但在大多数情况下,这将意味着对资源本身的双重访问(一次用于检查是否存在,另一次用于读取),并且在某些情况下可能是一个性能问题,例如基于远程 URL 的模板资源 —— 这个潜在的性能问题可能在很大程度上通过使用模板缓存得到缓解(在这种情况下,模板只在第一次被访问时被解析)。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号