package com.baeldung.thymeleaf.config; import java.util.Locale; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Description; import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; import org.springframework.web.servlet.i18n.SessionLocaleResolver; import org.thymeleaf.TemplateEngine; import org.thymeleaf.extras.java8time.dialect.Java8TimeDialect; import org.thymeleaf.spring4.SpringTemplateEngine; import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver; import org.thymeleaf.spring4.view.ThymeleafViewResolver; import org.thymeleaf.templatemode.TemplateMode; import org.thymeleaf.templateresolver.ITemplateResolver; import com.baeldung.thymeleaf.formatter.NameFormatter; import com.baeldung.thymeleaf.utils.ArrayUtil; import nz.net.ultraq.thymeleaf.LayoutDialect; import nz.net.ultraq.thymeleaf.decorators.strategies.GroupingStrategy; @Configuration @EnableWebMvc @ComponentScan({ "com.baeldung.thymeleaf" }) /** * Java configuration file that is used for Spring MVC and Thymeleaf * configurations */ public class WebMVCConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware { private ApplicationContext applicationContext; public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } @Bean public ViewResolver htmlViewResolver() { ThymeleafViewResolver resolver = new ThymeleafViewResolver(); resolver.setTemplateEngine(templateEngine(htmlTemplateResolver())); resolver.setContentType("text/html"); resolver.setCharacterEncoding("UTF-8"); resolver.setViewNames(ArrayUtil.array("*.html")); return resolver; } @Bean public ViewResolver javascriptViewResolver() { ThymeleafViewResolver resolver = new ThymeleafViewResolver(); resolver.setTemplateEngine(templateEngine(javascriptTemplateResolver())); resolver.setContentType("application/javascript"); resolver.setCharacterEncoding("UTF-8"); resolver.setViewNames(ArrayUtil.array("*.js")); return resolver; } @Bean public ViewResolver plainViewResolver() { ThymeleafViewResolver resolver = new ThymeleafViewResolver(); resolver.setTemplateEngine(templateEngine(plainTemplateResolver())); resolver.setContentType("text/plain"); resolver.setCharacterEncoding("UTF-8"); resolver.setViewNames(ArrayUtil.array("*.txt")); return resolver; } private TemplateEngine templateEngine(ITemplateResolver templateResolver) { SpringTemplateEngine engine = new SpringTemplateEngine(); engine.addDialect(new LayoutDialect(new GroupingStrategy())); engine.addDialect(new Java8TimeDialect()); engine.setTemplateResolver(templateResolver); engine.setTemplateEngineMessageSource(messageSource()); return engine; } private ITemplateResolver htmlTemplateResolver() { SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver(); resolver.setApplicationContext(applicationContext); resolver.setPrefix("/WEB-INF/views/"); resolver.setCacheable(false); resolver.setTemplateMode(TemplateMode.HTML); return resolver; } private ITemplateResolver javascriptTemplateResolver() { SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver(); resolver.setApplicationContext(applicationContext); resolver.setPrefix("/WEB-INF/js/"); resolver.setCacheable(false); resolver.setTemplateMode(TemplateMode.JAVASCRIPT); return resolver; } private ITemplateResolver plainTemplateResolver() { SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver(); resolver.setApplicationContext(applicationContext); resolver.setPrefix("/WEB-INF/txt/"); resolver.setCacheable(false); resolver.setTemplateMode(TemplateMode.TEXT); return resolver; } @Bean @Description("Spring Message Resolver") public ResourceBundleMessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("messages"); return messageSource; } @Bean public LocaleResolver localeResolver() { SessionLocaleResolver localeResolver = new SessionLocaleResolver(); localeResolver.setDefaultLocale(new Locale("en")); return localeResolver; } @Bean public LocaleChangeInterceptor localeChangeInterceptor() { LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor(); localeChangeInterceptor.setParamName("lang"); return localeChangeInterceptor; } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(localeChangeInterceptor()); } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").addResourceLocations("/WEB-INF/resources/"); } @Override @Description("Custom Conversion Service") public void addFormatters(FormatterRegistry registry) { registry.addFormatter(new NameFormatter()); } }