Настройка Thymeleaf в Spring
На просторах интернета можно найти такое решение:
@Configuration
@ComponentScan("com.concretepage")
@EnableWebMvc
public class AppConfig extends WebMvcConfigurerAdapter {
@Bean(name ="templateResolver")
public ServletContextTemplateResolver getTemplateResolver() {
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("XHTML");
return templateResolver;
}
@Bean(name ="templateEngine")
public SpringTemplateEngine getTemplateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(getTemplateResolver());
return templateEngine;
}
@Bean(name="viewResolver")
public ThymeleafViewResolver getViewResolver(){
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(getTemplateEngine());
return viewResolver;
}
...
Проблема его в том, что на локальном компьютере, будучи запущенным из IDEA без сборки в war, оно не работает.
Откуда-то я стащил такое решение:
@Bean // 1
public ViewResolver viewResolver(SpringTemplateEngine engine) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(engine);
return resolver;
}
@Bean // 2
public TemplateEngine templateEngine(TemplateResolver resolver) {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(resolver);
return engine;
}
@Bean
public TemplateResolver templateResolver() {
TemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/templates/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
return resolver;
}
Оно нормально работало, если не считать одного случая, о котором я благополучно забыл. Вспомнить пришлось уже в тот момент, когда я развёртывал сервлет. Шаблоны таки не находились.
Если запустить код «с покрывалом» или в режиме отладки, можно обнаружить, что в качестве SpringTemplateEngine (1) используется совсем не тот объект, который создаётся методом (2) — последний вообще не вызывается спрингом. Если поменять возвращаемое значение с TemplateEngine на SpringTemplateEngine, всё перестаёт работать: метод возвращает криво настроенный компонент, который впоследствии передаётся viewResolver'у.
Покопавшись в стандартном конфиге Thymeleaf, я родил это:
@Configuration
// ещё аннотации
public class Config extends WebMvcConfigurerAdapter implements ApplicationContextAware {
private ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
@Bean
public ThymeleafViewResolver viewResolver(SpringTemplateEngine engine) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(engine);
return resolver;
}
@Autowired
private final Collection templateResolvers = Collections.emptySet();
@Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.addTemplateResolver(templateResolver());
templateResolvers.forEach(engine::addTemplateResolver);
engine.addDialect("layout", new LayoutDialect());
engine.setMessageSource(context);
return engine;
}
@Bean
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/templates/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
...
Код приблизительно повторяет то, что внутри стандартного конфига Thymeleaf, и работает как будучи запущенным Идеей (/usr/lib/jvm/java-8-oracle/bin/java classpath и всё такое), так и на хостинге из Tomcat.