I am trying to create a Spring Boot 2.2.4 thymeleaf bilingual application (French and Arabic), here is the configuration I used, the problem is that when I switch to Arabic, I get this '?????? ?????'.
I tried so many character encodings but nothing worked.
#Configuration
#EnableWebMvc
#ComponentScan
public class ThymeleafConfiguration implements WebMvcConfigurer {
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(thymeleafTemplateResolver());
return templateEngine;
}
#Bean
public SpringResourceTemplateResolver thymeleafTemplateResolver() {
SpringResourceTemplateResolver templateResolver
= new SpringResourceTemplateResolver();
templateResolver.setPrefix("/WEB-INF/classes/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setCacheable(false);
return templateResolver;
}
#Bean
public ViewResolver viewResolver(){
ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver();
thymeleafViewResolver.setTemplateEngine(templateEngine());
thymeleafViewResolver.setCharacterEncoding("UTF-8");
return thymeleafViewResolver;
}
}
EDIT :
After closing and reopening the project, I noticed that arabic content in messages_ar.properties is converted to '???????? ????'
When I noticed that the file is converted to unrecognized characters after each reopening of the project, I started to dig and I discovered that it was about file encoding, so I changed it and it worked.
https://blog.jetbrains.com/idea/2013/03/use-the-utf-8-luke-file-encodings-in-intellij-idea/
Related
I've tried to configure controllers for thymeleaf views resolver, but it doesn't work. I made controller test and they passed so i think it is servlets configuration problem.
My WebConfig looks like this:
#Configuration
#EnableWebMvc
#ComponentScan("springmvccommerce.web")
public class WebConfig implements WebMvcConfigurer{
#Bean
ViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
return viewResolver;
}
#Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setCacheable(true);
return templateResolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.setEnableSpringELCompiler(true);
return templateEngine;
}
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
Edit:
HomeController:
#Controller
public class HomeController {
#GetMapping("/")
public String home() {
return "home";
}
}
And productController:
#Controller
public class ProductController {
#Autowired
private ProductRepository productRepository;
#GetMapping("/products")
public String products(Model model) {
model.addAttribute("productList", productRepository.findProduct(Long.MAX_VALUE, 20));
return "products";
}
}
If it is not enough, I've added link to repo in comment.
It seems spring boot haven't support for tomcat 10 due to the jakarta namespace, switch to tomcat 9 and retry.
Here are some links related:
https://github.com/spring-projects/spring-framework/issues/25354
Deploying Spring 5.x on Tomcat 10.x with jakarta.* package
I'm trying to configure a second template resolver to be used by Thymeleaf. I also want the default resolver which looks under the templates folder but whatever I try I only end up with a single resolver.
In my project there is already a yaml configuration file which contains:
thymeleaf:
mode: LEGACYHTML5
cache: false
As a first step I've tried to add a configuration bean:
#Configuration
#EnableWebMvc
public class ThymeleafConfiguration extends WebMvcConfigurerAdapter implements ApplicationContextAware
{
private ApplicationContext applicationContext;
#Override
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException
{
this.applicationContext = applicationContext;
}
#Bean
public TemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver());
return engine;
}
private ITemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("/public/");
resolver.setTemplateMode("HTML");
return resolver;
}
}
But I never see a second resolver in org.thymeleaf.TemplateRepository, just the default.
I've further tried omdifying the YAML file with the following:
thymeleaf:
-
mode: LEGACYHTML5
cache: false
prefix: classpath:/public/
-
mode: LEGACYHTML5
cache: false
prefix: classpath:/templates/
But again I only get a single resolver created.
Anyone know how to do this or can see what I am doing wrong?
If you want to add multiple resolvers, you could use engine.addTemplateResolver instead of engine.setTemplateResolver() or use setTemplateResolvers() which takes in a Set.
#Configuration
#EnableWebMvc
public class ThymeleafConfiguration extends WebMvcConfigurerAdapter implements ApplicationContextAware
{
private ApplicationContext applicationContext;
#Override
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException
{
this.applicationContext = applicationContext;
}
#Bean
public TemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.addTemplateResolver(templateResolverPublic());
engine.addTemplateResolver(templateResolverTemplates());
return engine;
}
private ITemplateResolver templateResolverPublic() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("/public/");
resolver.setTemplateMode("HTML");
return resolver;
}
private ITemplateResolver templateResolverTemplates() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("/templates/");
resolver.setTemplateMode("HTML");
return resolver;
}
}
P.S. On an other note if you want to use auto-configuration capabilities of Spring boot, you should avoid setting up your configuration manually (as you did in your configuration class) and instead just define properties in YAML which Spring Boot will use and will configure your template engine/resolvers. If you manually specify your configuration spring boot will not additionally configure the Thymeleaf engine/resolvers so the YAML properties w.r.t the configurations you defined will not be used i.e. you are basically overriding spring boots configurations.
I'm using springboot + thymeleaf and have just started setting up the project.
At first this worked fine, showing my home page and account page, but I must've changed something somewhere because now it will only show home.
weird stuff 1: It takes the template home from the resources/templates folder, although I've configured it to not do that. My guess is it doesn't use the configuration.
weird stuff 2: It only finds the home template, not the account template.
What do I need to change to get this working again?
Configuration class:
#SpringBootApplication
#RestController
#Configuration
#ComponentScan("applikaasie.domein")
public class startApp {
public static void main(String[] args) {
SpringApplication.run(startApp.class, args);
}
#Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine);
return viewResolver;
}
#Bean
public TemplateEngine templateEngine(TemplateResolver templateResolver) {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
return templateEngine;
}
#Bean
public TemplateResolver templateResolver() {
TemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/templates");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
System.out.println("templateResolver");
return templateResolver;
}
}
Account class:
#Controller
#RequestMapping(value="account")
public class AccountController {
#RequestMapping(value="/", method=GET)
public String greeting() {
return "home";
}
#RequestMapping(value="/accounts", method=RequestMethod.GET)
public String accountList(Model model) {
model.addAttribute(accountRepository.getAllAccounts());
return "accounts";
}
}
Directory structure:
/resources
/templates
account.html
home.html
/webapp
/WEB-INF
/templates
account.html
home.html
UPDATE
Resetting the computer fixed this. I guess something in memory was wrong.
I have a Spring MVC application with Thymeleaf view resolver. Here is my config class:
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public SpringResourceTemplateResolver springResourceTemplateResolver() {
return new SpringResourceTemplateResolver();
}
#Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
#Bean
public TemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setEnableSpringELCompiler(true);
engine.setTemplateResolver(templateResolver());
return engine;
}
private ITemplateResolver templateResolver() {
springResourceTemplateResolver().setPrefix("/WEB-INF/templates/");
springResourceTemplateResolver().setTemplateMode(TemplateMode.HTML);
return springResourceTemplateResolver();
}
}
Now I need to add a jsp resolver to the same application. I'm adding InternalResourceViewResolver bean but it doesn't work as expected:
#Bean
public InternalResourceViewResolver jspViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
Instead of getting test_jsp page when I go to /test/jsp I get an error:
#RequestMapping(value = "/test/leaf", method = RequestMethod.GET)
public String mainPage() {
return "test_html.html";
}
#RequestMapping(value = "/test/jsp", method = RequestMethod.GET)
public String mainPage2() {
return "test_jsp";
}
Request processing failed; nested exception is
org.thymeleaf.exceptions.TemplateInputException: An error happened
during template parsing (template: "ServletContext resource
[/WEB-INF/templates/test_jsp]")
Does anybody know how to add jsp view resolver when ThymeLeaf is already in place? I need Spring to look for Thymeleaf first and when page is not found then he searches jsp. Thanks
Set the order property on the ThymeleafViewResolver to a lower integer than other order properties on other resolvers. Zero makes sense for your case.
For your controller, you'll want to return just the page name and leave off the extension (.html).
Finally, post the full trace when you're posting error messages to SO. As it stands, there could also be an issue with your JSP but a reader here can't readily tell.
package com.mmm.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
#Configuration
#EnableWebMvc
#EnableAspectJAutoProxy
#ComponentScan(basePackages = "com.mmm")
public class MainConfig implements WebMvcConfigurer {
#Autowired
WebApplicationContext webApplicationContext;
#Bean
public SpringResourceTemplateResolver getTemplateResolver() {
SpringResourceTemplateResolver templateResolver = new
SpringResourceTemplateResolver();
templateResolver.setApplicationContext(webApplicationContext);
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
return templateResolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(getTemplateResolver());
templateEngine.setEnableSpringELCompiler(true);
return templateEngine;
}
#Bean
ThymeleafViewResolver configureViewResolvers() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setOrder(1);
resolver.setViewNames(new String[] {"*.html"});
return resolver;
}
#Bean
public UrlBasedViewResolver getUrlBasedViewResolver() {
UrlBasedViewResolver viewResolver = new UrlBasedViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix("");
viewResolver.setOrder(2);
return viewResolver;
}
I've tried a lot of solutions but it just doesn't work. I'm using Intellij 2016.1.
I can't force the app to resolve templates.
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Error resolving template "/login/login", template might not exist or might not be accessible by any of the configured Template Resolvers
config
#Configuration
#ComponentScan(basePackages = "com.unibooker")
#EnableWebMvc
public class Config extends WebMvcConfigurerAdapter{
#Bean
public TemplateResolver templateResolver() {
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setPrefix("classpath:/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
return templateResolver;
}
#Bean(name = "templateEngine")
public SpringTemplateEngine getTemplateEngine()
{
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(this.templateResolver());
templateEngine.setMessageSource(this.messageSource());
templateEngine.addDialect(new LayoutDialect());
return templateEngine;
}
#Bean
public ViewResolver setupViewResolver()
{
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(this.getTemplateEngine());
viewResolver.setOrder(1);
return viewResolver;
}
#Bean
public MessageSource messageSource()
{
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(3600);
return messageSource;
}
#Bean
public LocaleResolver localeResolver()
{
CookieLocaleResolver resolver = new CookieLocaleResolver();
resolver.setDefaultLocale(new Locale("pl"));
resolver.setCookieName("locale");
resolver.setCookieMaxAge(86400);
return resolver;
}
#Override
public void addInterceptors(InterceptorRegistry registry)
{
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("locale");
registry.addInterceptor(interceptor);
}
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
Project structure - IMAGE
I have tried to move templates to resources but still nothing. Please help. I have no more ideas how to fix this ... It worked earlier and then stopped.
Thymeleaf Resolver will look under templates/login/ for a login.html page. Based on your project structure and configuration, you rightly have a login folder inside template but you don't have a login.html inside the directory which is why the reason for the error.
Either create a login.html inside the login folder or use the index.html page which is already there. In your spring controller you should return the appropriate page.
For example,
Assuming that you need to show the login page your controller method should return,
return "login/login" // to display login.html under `templates/login`
or
return "login/index" // to display index.html under `templates/login`