【问题标题】:Spring Boot adding thymeleaf-layout-dialectSpring Boot 添加 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]

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

【问题讨论】:

标签: spring-mvc spring-boot thymeleaf


【解决方案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;
}

希望现在清楚了。

【讨论】:

    猜你喜欢
    • 2017-06-21
    • 1970-01-01
    • 1970-01-01
    • 2017-06-14
    • 2017-05-26
    • 2019-06-28
    • 2017-01-11
    • 1970-01-01
    • 2017-04-14
    相关资源
    最近更新 更多