Spring Boot Thymeleaf 多個Template Resolver設定

Spring Boot 內建其實就已經有Thymeleaf,基本上到application properties就可以設定了。但Spring Boot一開始的設定是給view template使用的,如果今天想要email也使用thymeleaf來產template,但想要用純文字檔呢?從spring.thymeleaf.mode看起來很像是無法讓我同時填HTML、TEXT,很像只能吃一種templateResolver。如果想要有多個templateResolver,除了爬文去找Spring Boot有沒有Interceptor或Configuration支援這樣子的設定,最快的方法就是乾脆不要用Spring Boot內建的Thymeleaf設定,改由自己設定比較快。

第一步: 停止內建的ThymeleafAutoConfiguration

@SpringBootApplication(exclude=org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration.class)

第二步: 自己引入Thymeleaf的依賴 (Gradle為例)

compile "org.springframework.boot:spring-boot-starter-thymeleaf
// https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring4
compile group: 'org.thymeleaf', name: 'thymeleaf-spring4', version: '3.0.6.RELEASE'
// https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf
compile group: 'org.thymeleaf', name: 'thymeleaf', version: '3.0.6.RELEASE'
// https://mvnrepository.com/artifact/nz.net.ultraq.thymeleaf/thymeleaf-layout-dialect
compile group: 'nz.net.ultraq.thymeleaf', name: 'thymeleaf-layout-dialect', version: '2.2.2'

第三步: 設定TemplateResolver (Java Config)

@Configuration
public class MyConfiguration implements ApplicationContextAware {

  private ApplicationContext applicationContext;

  ...
  
  @Bean
  public TemplateEngine templateEngine() {
    SpringTemplateEngine engine = new SpringTemplateEngine();
    engine.addTemplateResolver(textTemplateResolver());
    engine.addTemplateResolver(htmlTemplateResolver());
    return engine;
  }

  private ITemplateResolver textTemplateResolver() {
    SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
    resolver.setApplicationContext(applicationContext);
    resolver.setPrefix("classpath:/templates/");
    resolver.setSuffix(".txt");
    resolver.setTemplateMode("TEXT");
    resolver.setCacheable(false);
    resolver.setCharacterEncoding(StandardCharsets.UTF_8.toString());
    resolver.setOrder(1);
    return resolver;
  }

  private ITemplateResolver htmlTemplateResolver() {
    SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
    resolver.setApplicationContext(applicationContext);
    resolver.setPrefix("classpath:/templates/");
    resolver.setSuffix(".html");
    resolver.setTemplateMode("HTML");
    resolver.setCacheable(false);
    resolver.setCharacterEncoding(StandardCharsets.UTF_8.toString());
    resolver.setOrder(2);
    return resolver;
  }

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    this.applicationContext = applicationContext;
  }
}

第四步: 應用

Context context = new Context(Locale.getDefault());
context.setVariable("today", "123");
templateEngine.process("email.html", context);
templateEngine.process("plaintEmail.txt", context);

第四步也是自己一直卡關的地方,原以為加了兩個templateResolver,各自Suffix也不一樣,Thymeleaf會聰明的自己判斷(根據Order或是路徑…也不確定)採用正確副檔名的template,不過看起來很像沒這回事,最後還是要特別加上副檔名名稱才可以正常分別吃到對應的template。但不管怎樣,上述設定的確有做到的我想要的結果。

參考:

  • http://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html

Leave a Reply

當第一個留言者!

avatar