开发学院

您的位置:首页>教程>正文

教程正文

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,则调用链中的以下解析器)。虽然这在每种情况下听起来都不错,但在大多数情况下,这意味着对资源本身的双重访问(一次用于检查是否存在,另一次用于读取),并且在某些情况下可能是一个性能问题,例如基于远程网址的模板资源,这是一个潜在的性能问题,无论如何都可能通过模板缓存的使用而大大减轻(在这种情况下,模板只能在第一次访问时解决)。