Настройка 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.


← клик, если это интересно   |   ↓ место для вопросов и идей