I have a spring boot application which is working as an OAuth2 client.
I'm using Thymeleaf 3 as template engine. These are the Thymeleaf 3 related dependencies in my build.gradle.
compile('org.thymeleaf:thymeleaf:3.0.1.RELEASE')
compile('org.thymeleaf:thymeleaf-spring4:3.0.1.RELEASE')
compile('nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:2.0.4')
compile('org.thymeleaf.extras:thymeleaf-extras-springsecurity4:3.0.1.RELEASE')
It makes no difference if I reference the dependencies like this:
ext["thymeleaf.version"] = "3.0.2.RELEASE"
ext["thymeleaf-layout-dialect.version"] = "2.1.1"
dependencies {
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
}
I want to be able to use Thymeleaf 3's HTML and Javascript template modes.
HTML mode works, but in javascript mode the messageSource is not working properly.
Here is my WebMvcConfiguration class:
#Configuration
public class WebMVCConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware {
private static final String CHARACTER_ENCODING = "UTF-8";
private ApplicationContext applicationContext;
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
#Bean
public ViewResolver htmlViewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine(htmlTemplateResolver()));
resolver.setContentType("text/html");
resolver.setCharacterEncoding(CHARACTER_ENCODING);
resolver.setViewNames(new String[] {"*.html"});
return resolver;
}
#Bean
public ViewResolver javascriptViewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine(javascriptTemplateResolver()));
resolver.setContentType("application/javascript");
resolver.setCharacterEncoding(CHARACTER_ENCODING);
resolver.setViewNames(new String[] {"*.js"});
return resolver;
}
private TemplateEngine templateEngine(ITemplateResolver templateResolver) {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver);
return engine;
}
private ITemplateResolver htmlTemplateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("templates/");
resolver.setCacheable(false);
resolver.setTemplateMode(TemplateMode.HTML);
resolver.setSuffix(".html");
return resolver;
}
public ITemplateResolver javascriptTemplateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("classpath:/static/js/");
resolver.setCacheable(false);
resolver.setTemplateMode(TemplateMode.JAVASCRIPT);
// resolver.setSuffix(".js");
return resolver;
}
}
Please note that I had to use "classpath:/static/js/" in javascriptTemplateResolver, because when I used only "static/js/", I got the following exception:
java.io.FileNotFoundException: Could not open ServletContext resource [/static/js/headerconfig.js]
Also I had to comment out setSuffix, because with it I get the following exception:
java.io.FileNotFoundException: class path resource [static/js/typeutils.js.js] cannot be opened because it does not exist
I think this already indicates the main problem but I can't figure out what may cause it.
I have a controller for handling javascript templates:
#Controller
public class JavascriptController {
#RequestMapping(method = RequestMethod.GET, value = "/js/{template}.js")
public String jsMapping(#PathVariable("template") String template, Model model) {
model.addAttribute("myAttribute", "Attribute works!");
return template;
}
}
My messages.properties files are located in
src/main/resources/messages.properties
src/main/resources/messages_hu.properties
I have an HTML file in src/main/resources/templates/ folder, which references a javascript file like so:
<script th:src="#{js/typeutils.js}"></script>
The referenced javascript file (js/typeutils.js):
var a = [[${myAttribute}]];
var b = [[#{test}]];
console.log(a);
console.log(b);
When I run the application and check the javascript console, this is what's being printed out:
Attribute works!
??test_hu_HU??
So the model attribute was successfully passed to the javascript file, and the localization has been detected, but the message wasn't found for 'test'.
It seems as if the javascript template mode behaves completely different from HTML template mode.
How should if fix the javascript template mode config in order for it to process the messages.properties files, too?
Thanks!
I figured out the solution (by looking through thymeleaf sourcecode), which might not be perfect, but it works!
Unlike the example given by Baeldung, the following solved the problem for me:
#Configuration
public class WebMVCConfig implements WebMvcConfigurer, ApplicationContextAware {
private static final String CHARACTER_ENCODING = "UTF-8";
private ApplicationContext applicationContext;
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
#Bean
public ViewResolver htmlViewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setContentType("text/html");
resolver.setCharacterEncoding(CHARACTER_ENCODING);
resolver.setViewNames(new String[] { "*.html" });
return resolver;
}
#Bean
public ViewResolver javascriptViewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setContentType("application/javascript");
resolver.setCharacterEncoding(CHARACTER_ENCODING);
resolver.setViewNames(new String[] { "*.js" });
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setMessageSource(messageSource());
engine.addTemplateResolver(htmlTemplateResolver());
engine.addTemplateResolver(javascriptTemplateResolver());
return engine;
}
private ITemplateResolver htmlTemplateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setOrder(0);
resolver.setCheckExistence(true);
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("classpath:templates/");
resolver.setCacheable(false);
resolver.setTemplateMode(TemplateMode.HTML);
resolver.setSuffix(".html");
return resolver;
}
public ITemplateResolver javascriptTemplateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setOrder(1);
resolver.setCheckExistence(true);
resolver.setPrefix("classpath:/static/js/");
resolver.setCacheable(false);
resolver.setTemplateMode(TemplateMode.JAVASCRIPT);
return resolver;
}
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource msgSource = new ResourceBundleMessageSource();
msgSource.setAlwaysUseMessageFormat(false);
msgSource.setBasename("messages");
msgSource.setDefaultEncoding(CHARACTER_ENCODING);
msgSource.setFallbackToSystemLocale(true);
msgSource.setUseCodeAsDefaultMessage(false);
return msgSource;
}
}
Basically what happens is we set templateEngine to be a bean, so that we override ThymeleafDefaultConfiguration's default templateEngine implementation bean. This means that each time a template needs to be resolved, the same templateEngine will be used for sure.
We set the order of the htmlTemplateResolver to be 0, and the order of the javascriptTemplateResolver to be 1, so that we will try to resolve each template first in HTML template mode, then in Javascript mode.
It's important, too, that we set the checkExistence flag of the SpringResourceTemplateResolvers to true, because this way if a template can't be found, we will try with the next TemplateResolver.
There is one drawback of this solution, which is we will try to resolve javascript templates unnecessary in HTML mode first, then in JAVASCRIPT mode, so there is an extra step when resolving javascript resources.
I will try to solve the problem better but for now, this works for me.
Related
I have a spring-boot + thymeleaf application - so im basicly using no xml files for configuration. Classic html templates work fine for me, but i am having troubles with xsl. I followed this tutorial Spring MVC XstlView and XsltViewResolver Example but ended up with java.io.FileNotFoundException: Could not open ServletContext resource [/templates/show.xsl]
This is how my configuration class looks like
#Configuration
#EnableWebMvc
public class MvcConfiguration extends WebMvcConfigurerAdapter {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/" };
#Bean
#Description("Thymeleaf template resolver serving HTML 5")
public ClassLoaderTemplateResolver htmlTemplateResolver() {
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setPrefix("templates/");
templateResolver.setCacheable(false);
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
templateResolver.setCharacterEncoding("UTF-8");
return templateResolver;
}
#Bean
#Description("Thymeleaf template resolver serving XML")
public ClassLoaderTemplateResolver xmlTemplateResolver() {
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setPrefix("templates/");
templateResolver.setCacheable(false);
templateResolver.setSuffix(".xml");
templateResolver.setTemplateMode("XML");
templateResolver.setCharacterEncoding("UTF-8");
return templateResolver;
}
#Bean
#Description("Thymeleaf template engine with Spring integration")
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.addTemplateResolver(htmlTemplateResolver());
templateEngine.addTemplateResolver(xmlTemplateResolver());
return templateEngine;
}
#Bean
#Description("Thymeleaf view resolver")
public ViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setCharacterEncoding("UTF-8");
return viewResolver;
}
#Bean
public ViewResolver getXSLTViewResolver(){
XsltViewResolver xsltViewResolver = new XsltViewResolver();
xsltViewResolver.setOrder(1);
xsltViewResolver.setSourceKey("xmlSource");
xsltViewResolver.setViewClass(XsltView.class);
xsltViewResolver.setViewNames(new String[] {"show"});
xsltViewResolver.setPrefix("templates/");
xsltViewResolver.setSuffix(".xsl");
return xsltViewResolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!registry.hasMappingForPattern("/webjars/**")) {
registry.addResourceHandler("/webjars/**").addResourceLocations(
"classpath:/META-INF/resources/webjars/");
}
if (!registry.hasMappingForPattern("/**")) {
registry.addResourceHandler("/**").addResourceLocations(
CLASSPATH_RESOURCE_LOCATIONS);
}
}
}
From controller i am trying to redirect to my xsl template like this:
#RequestMapping(value="/form", method=RequestMethod.POST, params="action=show")
public ModelAndView show(#ModelAttribute Team team) throws MarshalException {
Source source = new StreamSource(new ByteArrayInputStream(xmlService.getXmlStream(team).toByteArray()));
// adds the XML source file to the model so the XsltView can detect
ModelAndView model = new ModelAndView("show");
model.addObject("xmlSource", source);
return model;
}
This is how my project files look like.
I would appreciate any suggestions how to make it work. Thank you
If you are using spring boot, then, no need to mention any configuration setting like, TemplateMode, Prefix, Suffix, etc. Spring boot automatically configures the template as per default setting.
Do no mention any configuration in #Configuration class or application.properties file.
Try this, it worked for me.
I have a weird problem with my configuration. I'm trying to configure apache tiles with thymeleaf. I'm trying to do the same things they are on theirs documentation page.
I have following configuration file:
#Configuration
public class ViewConfig {
#Bean
public ViewResolver tilesViewResolver() {
ThymeleafViewResolver vr = new ThymeleafViewResolver();
vr.setTemplateEngine(templateEngine());
vr.setViewClass(ThymeleafTilesView.class);
vr.setCharacterEncoding("UTF-8");
vr.setOrder(Ordered.LOWEST_PRECEDENCE);
return vr;
}
#Bean
public ViewResolver thymeleafViewResolver() {
ThymeleafViewResolver vr = new ThymeleafViewResolver();
vr.setTemplateEngine(templateEngine());
vr.setCharacterEncoding("UTF-8");
vr.setOrder(Ordered.HIGHEST_PRECEDENCE);
// all message/* views will not be handled by this resolver;
vr.setExcludedViewNames(new String[]{"message/*"});
return vr;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.addDialect(new TilesDialect());
templateEngine.setTemplateResolver(templateResolver());
return templateEngine;
}
#Bean
public ThymeleafTilesConfigurer tilesConfigurer() {
ThymeleafTilesConfigurer ttc = new ThymeleafTilesConfigurer();
ttc.setValidateDefinitions(false);
ttc.setDefinitions(new String[]{"/templates/tiles-defs.xml"});
return ttc;
}
#Bean
public TemplateResolver templateResolver() {
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setSuffix(".html");
resolver.setPrefix("templates/");
resolver.setTemplateMode("HTML5");
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
}
I've added TemplateResolver for my purposes, but removing it doesn't help (for having the same configuration as documentation).
This is my resource folder structure:
And the problem is that I've got following exception:
Caused by: java.io.FileNotFoundException: ServletContext resource [/templates/tiles-defs.xml] cannot be resolved to URL because it does not exist
The most interesting is that I've checked target/classes (which is in classpath) and there is the file templates/tiles-defs.xml.
I've tried a couple of times to change the definition path (also I've tried to remove definition and get it from default WEB-INF/tiles.xml path) but no outcome - same exception.
What I'm doing wrong?
Here is how I solved it:
#Bean
public ThymeleafTilesConfigurer tilesConfigurer() {
ThymeleafTilesConfigurer ttc = new ThymeleafTilesConfigurer();
//ttc.setValidateDefinitions(false);
ttc.setDefinitions(ThymeleafProperties.DEFAULT_PREFIX + "tiles-defs.xml");
return ttc;
}
My application's Thymeleaf config is set as:
#Bean
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setCacheable(false);
templateResolver.setTemplateMode("HTML5");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setPrefix(HTML_VIEWS);
templateResolver.setSuffix(".html");
return templateResolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.addDialect(new SpringSecurityDialect());
templateEngine.addDialect(new LayoutDialect(new GroupingStrategy()));
templateEngine.setTemplateResolver(templateResolver());
return templateEngine;
}
#Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setCache(false);
viewResolver.setOrder(1);
return viewResolver;
}
OS (CentOS 7) default encoding is UTF-8 and all generated files get UTF-8 enconding. Still I cannot seem to be able to display characters correctly. I tried a bunch of suggestions found here, to no avail.
I have also tried, as per some suggestions here, setting a CharacterEncodingFilter prior to CsrfFilter in my Spring Security configuration. Also, the app is persisting the data WITH the strange characters.
My securitu configuration starts with:
#Override
protected void configure(HttpSecurity http) throws Exception {
CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
encodingFilter.setEncoding("UTF-8");
encodingFilter.setForceEncoding(true);
http.addFilterBefore(encodingFilter,CsrfFilter.class);
// more security configs
}
What am I missing?
The damned messages_pt_BR.properties file had a different encoding from the rest of the app... It decided to go with ISO-8859-1. Beats me why!
I'm trying to send a rich text email using Thymeleaf + Spring 4. I've followed the example on Thymeleaf's website but for some reason it's throwing an exception.
Here is my config:
#Bean
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".html");
resolver.setCharacterEncoding("UTF-8");
resolver.setTemplateMode("HTML5");
resolver.setOrder(2);
return resolver;
}
#Bean
public ClassLoaderTemplateResolver emailTemplateResolver() {
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
resolver.setPrefix("/WEB-INF/views/mail/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
resolver.setCharacterEncoding("UTF8");
resolver.setOrder(1);
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
final SpringTemplateEngine engine = new SpringTemplateEngine();
final Set<TemplateResolver> templateResolvers = new HashSet<TemplateResolver>();
templateResolvers.add(templateResolver());
templateResolvers.add(emailTemplateResolver());
engine.setTemplateResolvers(templateResolvers);
return engine;
}
As you can see from the above config, I've two resolvers; one for the pages and one for the email template. Based on the research I've done online when I try to fire up an email using the template that I have, it is trying to use the templateResolver() instead of the emailTemplateResolver() although orders are set correctly.
Here is my email service:
Autowired
private JavaMailSender mailSender;
#Autowired
private TemplateEngine templateEngine;
private static Logger logger = LoggerFactory.getLogger(EmailService.class);
/*
* Send HTML mail (simple)
*/
public void sendSimpleMail(final Locale locale)
throws MessagingException {
final String recipientName = "Name";
final String recipientEmail = "Email";
// Prepare the evaluation context
final Context ctx = new Context(locale);
ctx.setVariable("name", recipientName);
// Prepare message using a Spring helper
final MimeMessage mimeMessage = this.mailSender.createMimeMessage();
final MimeMessageHelper message = new MimeMessageHelper(mimeMessage, "UTF-8");
message.setSubject("Example HTML email (simple)");
message.setFrom("thymeleaf#example.com");
message.setTo(recipientEmail);
// Create the HTML body using Thymeleaf
final String htmlContent = this.templateEngine.process("email-simple", ctx);
message.setText(htmlContent, true /* isHtml */);
// Send email
this.mailSender.send(mimeMessage);
}
Here is the exception that is being thrown:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Resource resolution by ServletContext with org.thymeleaf.resourceresolver.ServletContextResourceResolver can only be performed when context implements org.thymeleaf.context.IWebContext [current context: org.thymeleaf.context.Context]
Has anyone had any ideas how I can resolve this issue?
Thanks in advance
Hey I ran into this issue before and after some research I found a way around it. Change your Java config to something like this, you will also have to move your html content to /WEB-INF/classes/mail/ because ClassLoaderTemplateResolver looks in the classes directory for your files.
#Bean
public TemplateResolver templateResolver() {
TemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".html");
resolver.setCharacterEncoding("UTF-8");
resolver.setTemplateMode("HTML5");
resolver.setOrder(2);
return resolver;
}
#Bean
public TemplateResolver emailTemplateResolver() {
TemplateResolver resolver = new ClassLoaderTemplateResolver();
resolver.setPrefix("mail/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
resolver.setCharacterEncoding("UTF-8");
resolver.setOrder(1);
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
final SpringTemplateEngine engine = new SpringTemplateEngine();
final Set<TemplateResolver> templateResolvers = new HashSet<TemplateResolver>();
templateResolvers.add(emailTemplateResolver());
templateResolvers.add(templateResolver());
engine.setTemplateResolvers(templateResolvers);
return engine;
}
Hopefully this helps!
Below Code will help will work
WebContext wc=new WebContext(request,response,servletContext,request.getLocale());//servletContext Spring Context
MimeMessage message = this.mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
wc.setVariable("name", "abc");// If you want to pass params to Template
final String htmlContent = this.templateEngine.process("TemplateName", wc);
I'm worked with Spring in the past on a big project, but I've never started a Spring MVC web app from scratch.
Well that's what I'm currently doing now for practice as I have a project coming up that will require it.
I was successfully able to make a simple Spring MVC Web App that used .JSP pages (using annotations, no XML).
I wanted to use Thymeleaf though and started my conversion process to that.
Well now I'm getting a 404 Error and my HomeController class isn't even being hit it seems like.
I get no errors in the Console output.
I've Google search, read through tutorials, and code samples. Second pair of eyes would be nice. Thanks! :)
Note: going from .JSP to Thymeleaf the only changes made was the addition of the ThymeleafConfig class. I don't see how it went from working to not working.
Here's my code:
WebInit.java
public class WebInit implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
// Creates the root application context
AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
appContext.register(ServletConfig.class);
appContext.setDisplayName("REPLACE ME");
appContext.setConfigLocation("com.demo.config");
// Creates the Spring Container shared by all Servlets and Filters
servletContext.addListener(new ContextLoaderListener(appContext));
// Further configures the servlet context
ServletRegistration.Dynamic dispatcher = servletContext.addServlet(
"dispatcher", new DispatcherServlet(appContext));
dispatcher.setLoadOnStartup(1);
dispatcher.setAsyncSupported(true);
dispatcher.addMapping("/");
}
}
ServetConfig.java
#Configuration
#Import(WebConfig.class)
#ImportResource({/*"classpath:META-INF/spring/persistence-context.xml"*/})
public class ServletConfig {
}
WebConfig.java
#Configuration
#ComponentScan("com.illinois.dnr")
#EnableAspectJAutoProxy
#EnableWebMvc
#Import({ThymeleafConfig.class})
public class WebConfig extends WebMvcConfigurerAdapter {
// Maps resources path to webapp/resources
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations(
"/resources/");
}
// Provides internationalization of messages
#Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasename("messages");
return source;
}
}
Thymeleaf.java
#Configuration
public class ThymeleafConfig {
#Bean
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
resolver.setOrder(1);
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver());
return engine;
}
#Bean
public ThymeleafViewResolver thymeleafViewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
return resolver;
}
}
HomeController.java
#Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
/**
* Simply selects the home view to render by returning its name.
*/
#RequestMapping(value = "/dnr", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! The client locale is {}.", locale);
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,
DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate);
return "home";
}
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String loginPage(Locale locale, Model model) {
logger.info("Login");
return "login";
}
#RequestMapping(value = "/home", method = RequestMethod.POST)
public String login(#Validated User user, Model model) {
model.addAttribute("userName", user.getUserName());
logger.info("User");
return "user";
}
#RequestMapping(value = { "/", "/welcome**" }, method = RequestMethod.GET)
public ModelAndView welcomePage() {
ModelAndView model = new ModelAndView();
model.addObject("title", "Spring Security Hello World");
model.addObject("message", "This is welcome page!");
model.setViewName("hello");
logger.info("Hello");
return model;
}
#RequestMapping(value = "/admin**", method = RequestMethod.GET)
public ModelAndView adminPage() {
ModelAndView model = new ModelAndView();
model.addObject("title", "Spring Security Hello World");
model.addObject("message", "This is protected page - Admin Page!");
model.setViewName("admin");
logger.info("admin");
return model;
}
#RequestMapping(value = "/dba**", method = RequestMethod.GET)
public ModelAndView dbaPage() {
ModelAndView model = new ModelAndView();
model.addObject("title", "Spring Security Hello World");
model.addObject("message", "This is protected page - Database Page!");
model.setViewName("admin");
logger.info("dba");
return model;
}
}
I'm not sure if it helps but you can simplified WebInit by extendsAbstractAnnotationConfigDispatcherServletInitializer instead of implements WebApplicationInitializer. Otherwise Thymeleaf configuration seems ok to me (suppose it's called). I'm giving here working skeleton of config so you can experiment with it.
WebApplicationInitializer
public class WebInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
WebConfig
#Configuration
#EnableWebMvc
#ComponentScan("com.kreuzman")
public class WebConfig {
#Bean
public ITemplateResolver templateResolver() {
TemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/templates/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
resolver.setCacheTTLMs(0l);
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver());
return engine;
}
#Bean
public ViewResolver thymeleafViewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setCharacterEncoding("UTF-8");
return viewResolver;
}
}
What page are you trying to hit? Does that html page exist in /WEB-INF/views/?
Is it a JSP page? you need to exclude all pages that are not going to be resolved by ThymeleafViewResolver. I also noticed you didn't set the ThymeleafViewResolver to first in the order.
Like so
#Bean
public ThymeleafViewResolver thymeleafViewResolver()
{
String[] excludedViews = new String[]{
"login", "logout"};
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
/*
* This is how we get around Thymeleaf view resolvers throwing an error instead of returning
* of null and allowing the next view resolver in the {#see
* DispatcherServlet#resolveViewName(String, Map<String, Object>, Locale,
* HttpServletRequest)} to resolve the view.
*/
resolver.setExcludedViewNames(excludedViews);
resolver.setOrder(1);
return resolver;
}