Spring Boot 添加 thymeleaf-layout-dialect

Posted

技术标签:

【中文标题】Spring Boot 添加 thymeleaf-layout-dialect【英文标题】:Spring Boot adding thymeleaf-layout-dialect 【发布时间】:2017-09-10 22:34:11 【问题描述】:

我正在使用 spring boot (v1.5.3.BUILD-SNAPSHOT) 我是 Spring Boot 新手。

使用渐变

请注意,普通的百里香方言可以正常工作(th:...) spring-boot-starter-thymeleaf\1.5.3.BUILD-SNAPSHOT

我想添加 thymeleaf-layout-dialect 我添加了依赖

compile('nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect')

documentation 表示通过执行以下操作添加方言

TemplateEngine templateEngine = new TemplateEngine();  // Or 
SpringTemplateEngine for Spring config
templateEngine.addDialect(new LayoutDialect());

所以我添加了一个配置类

@Configuration
public class MyConfiguration 


@Bean
public SpringTemplateEngine templateEngine()
    SpringTemplateEngine templateEngine  = new SpringTemplateEngine();
    templateEngine.addDialect(new LayoutDialect());
    return templateEngine;


但是当我尝试运行应用程序时,我收到以下错误

org.thymeleaf.exceptions.ConfigurationException: Cannot initialize: no template resolvers have been set
at org.thymeleaf.Configuration.initialize(Configuration.java:203) ~[thymeleaf-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.thymeleaf.TemplateEngine.initialize(TemplateEngine.java:827) ~[thymeleaf-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.thymeleaf.spring4.view.ThymeleafView.renderFragment(ThymeleafView.java:203) ~[thymeleaf-spring4-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.thymeleaf.spring4.view.ThymeleafView.render(ThymeleafView.java:190) ~[thymeleaf-spring4-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1282) ~[spring-webmvc-4.3.8.BUILD-SNAPSHOT.jar:4.3.8.BUILD-SNAPSHOT]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1037) ~[spring-webmvc-4.3.8.BUILD-SNAPSHOT.jar:4.3.8.BUILD-SNAPSHOT]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:980) ~[spring-webmvc-4.3.8.BUILD-SNAPSHOT.jar:4.3.8.BUILD-SNAPSHOT]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) ~[spring-webmvc-4.3.8.BUILD-SNAPSHOT.jar:4.3.8.BUILD-SNAPSHOT]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.8.BUILD-SNAPSHOT.jar:4.3.8.BUILD-SNAPSHOT]

谁能告诉我如何正确添加百里香布局方言?

【问题讨论】:

您能否检查一下这是否有帮助:***.com/questions/43197416/… 【参考方案1】:

问题是:

org.thymeleaf.exceptions.ConfigurationException: Cannot initialize: no template resolvers have been set

要将 Thymeleaf 与 Spring 集成,需要配置 3 个 bean:

ThymeleafViewResolver Bean - 您将使用模板引擎对其进行设置 SpringTemplateEngine Bean - 您将使用模板解析器对其进行设置 模板解析器 Bean

在您的 templateEngine bean 中,您没有设置任何模板解析器,因此您可以更改您的 templateEngine() 方法如下:

@Bean
public SpringTemplateEngine templateEngine(TemplateResolver templateResolver)
    SpringTemplateEngine templateEngine  = new SpringTemplateEngine();
    templateEngine.setTemplateResolver(templateResolver);       
    templateEngine.addDialect(new LayoutDialect());
    return templateEngine;

Spring 将为您提供SpringTemplateEnginetemplateResolver bean。


顺便说一句如果你定义spring-boot-starter-thymeleaf作为依赖,它会提供thymeleaf-layout-dialect作为一个方便版本的依赖,然后Spring会使用ThymeleafAutoConfiguration.java - Spring Boot 1.5.x为三个需要的bean配置一个默认bean豆子。

例如:

LayoutDialect bean 在这里定义 ThymeleafWebLayoutConfiguration.ThymeleafWebLayoutConfiguration():

@Configuration
@ConditionalOnClass(name = "nz.net.ultraq.thymeleaf.LayoutDialect")
protected static class ThymeleafWebLayoutConfiguration 

    @Bean
    @ConditionalOnMissingBean
    public LayoutDialect layoutDialect() 
        return new LayoutDialect();
    


SpringTemplateEngine bean 使用模板解析器和方言从这里定义ThymeleafWebLayoutConfiguration.ThymeleafDefaultConfiguration():

@Configuration
@ConditionalOnMissingBean(SpringTemplateEngine.class)
protected static class ThymeleafDefaultConfiguration 

  private final Collection<ITemplateResolver> templateResolvers;

  private final Collection<IDialect> dialects;

  public ThymeleafDefaultConfiguration(
      Collection<ITemplateResolver> templateResolvers,
      ObjectProvider<Collection<IDialect>> dialectsProvider) 
    this.templateResolvers = templateResolvers;
    this.dialects = dialectsProvider.getIfAvailable();
  

  @Bean
  public SpringTemplateEngine templateEngine() 
    SpringTemplateEngine engine = new SpringTemplateEngine();
    for (ITemplateResolver templateResolver : this.templateResolvers) 
      engine.addTemplateResolver(templateResolver);
    
    if (!CollectionUtils.isEmpty(this.dialects)) 
      for (IDialect dialect : this.dialects) 
        engine.addDialect(dialect);
      
    
    return engine;
  


最后在这里定义了一个thymeleafViewResolver bean AbstractThymeleafViewResolverConfiguration.thymeleafViewResolver():

@Bean
@ConditionalOnMissingBean(name = "thymeleafViewResolver")
@ConditionalOnProperty(name = "spring.thymeleaf.enabled", matchIfMissing = true)
public ThymeleafViewResolver thymeleafViewResolver() 
    ThymeleafViewResolver resolver = new ThymeleafViewResolver();
    configureTemplateEngine(resolver, this.templateEngine);
    resolver.setCharacterEncoding(this.properties.getEncoding().name());
    resolver.setContentType(appendCharset(this.properties.getContentType(),
        resolver.getCharacterEncoding()));
    resolver.setExcludedViewNames(this.properties.getExcludedViewNames());
    resolver.setViewNames(this.properties.getViewNames());
    // This resolver acts as a fallback resolver (e.g. like a
    // InternalResourceViewResolver) so it needs to have low precedence
    resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 5);
    resolver.setCache(this.properties.isCache());
    return resolver;

ThymeleafAutoConfiguration.Thymeleaf2ViewResolverConfiguration扩展:

@Bean
@ConditionalOnMissingBean(name = "thymeleafViewResolver")
@ConditionalOnProperty(name = "spring.thymeleaf.enabled", matchIfMissing = true)
public ThymeleafViewResolver thymeleafViewResolver() 
    ThymeleafViewResolver resolver = new ThymeleafViewResolver();
    configureTemplateEngine(resolver, this.templateEngine);
    resolver.setCharacterEncoding(this.properties.getEncoding().name());
    resolver.setContentType(appendCharset(this.properties.getContentType(),
        resolver.getCharacterEncoding()));
    resolver.setExcludedViewNames(this.properties.getExcludedViewNames());
    resolver.setViewNames(this.properties.getViewNames());
    // This resolver acts as a fallback resolver (e.g. like a
    // InternalResourceViewResolver) so it needs to have low precedence
    resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 5);
    resolver.setCache(this.properties.isCache());
    return resolver;

希望现在清楚了。

【讨论】:

以上是关于Spring Boot 添加 thymeleaf-layout-dialect的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot中添加Thymeleaf模板

如何将 Thymeleaf SpringSecurityDialect 添加到 Spring Boot

如何将布局方言添加到spring-boot thymeleaf自动配置文件

Spring Boot 2.0 整合Thymeleaf 模板引擎

Spring Boot 学习笔记--整合Thymeleaf

如何添加到 Thymeleaf/Spring Boot 发布请求中的子对象列表