I'm trying to pass some information from a browser to my server and end up having '????' symbols. I thoroughly searched for this problem on the Internet and StackOverFlow but in the end nothing helped me. My assumption is Thymeleaf/Spring continues to use ISO_8859_1 charset instead of UTF-8.
DispatcherServlet(CharacterEncodingFilter):
public class DispatcherServlet extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
public void onStartup(ServletContext aServletContext) throws ServletException {
super.onStartup(aServletContext);
registerCharacterEncodingFilter(aServletContext);
registerHiddenFieldFilter(aServletContext);
}
private void registerHiddenFieldFilter(ServletContext aContext) {
aContext.addFilter("hiddenHttpMethodFilter",
new HiddenHttpMethodFilter()).addMappingForUrlPatterns(null, true, "/*");
}
private void registerCharacterEncodingFilter(ServletContext aContext) {
EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST,
DispatcherType.FORWARD);
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
FilterRegistration.Dynamic characterEncoding = aContext.addFilter("characterEncoding",
characterEncodingFilter);
characterEncoding.addMappingForUrlPatterns(dispatcherTypes, true, "/*");
}
}
My Configuration:
public class ApplicationConfiguration implements WebMvcConfigurer {
private final ApplicationContext applicationContext;
private final Environment environment;
#Autowired
public ApplicationConfiguration(ApplicationContext applicationContext,
Environment environment) {
this.applicationContext = applicationContext;
this.environment = environment;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry resourceHandlerRegistry) {
resourceHandlerRegistry.addResourceHandler("/resources/**").
addResourceLocations("/resources/");
}
// Themyleaf resolver,engine etc
#Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("/WEB-INF/view/");
resolver.setSuffix(".html");
resolver.setCharacterEncoding("UTF-8");
resolver.setTemplateMode("HTML5");
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver());
engine.addDialect(new SpringSecurityDialect());
engine.setEnableSpringELCompiler(true);
return engine;
}
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setContentType("text/html; charset=UTF-8");
resolver.setCharacterEncoding("UTF-8");
registry.viewResolver(resolver);
}
}
As I've already said, I'm trying to make Spring/Thymeleaf use UTF-8 charset instead of the standard one. Certainly I could use something like
byte[] bytes = content.getBytes(StandardCharsets.ISO_8859_1);
content = new String(bytes, StandardCharsets.UTF_8);
but I'd like to have it done by Spring/Thymeleaf if it's possible.
UPD: Whatever the input data is I always see '???' in the console. For instance: 'Текстовая строка123' produces '???µ???????????°?? ???????????°123' (except for Non Cyrillic symbols)
Related
i have this project structure
--> src/main/java
--> src/main/resources/static/myFolder/css/common.css
i have this configuration class
#Configuration
public class WebFlowConfig extends AbstractFlowConfiguration {
#Autowired
private LocalValidatorFactoryBean localValidatorFacotryBean;
#Bean
public FlowDefinitionRegistry flowRegistry() {
return getFlowDefinitionRegistryBuilder()
.setBasePath("classpath:flow")
.addFlowLocationPattern("/myflows/myflow1.xml")
.addFlowLocationPattern("/myflows/myflow2.xml")
.setFlowBuilderServices(this.flowBuilderServices())
.build();
}
#Bean
public FlowExecutor flowExecutor() {
return getFlowExecutorBuilder(this.flowRegistry()) //
.build();
}
#Bean
public FlowBuilderServices flowBuilderServices() {
return getFlowBuilderServicesBuilder() //
.setViewFactoryCreator(this.mvcViewFactoryCreator()) // Important!
.setValidator(this.localValidatorFacotryBean).build();
}
// ----------------------------------------------------------
#Bean
public FlowHandlerMapping flowHandlerMapping() {
FlowHandlerMapping handlerMapping = new FlowHandlerMapping();
handlerMapping.setOrder(-1);
handlerMapping.setFlowRegistry(this.flowRegistry());
return handlerMapping;
}
#Bean
public FlowHandlerAdapter flowHandlerAdapter() {
FlowHandlerAdapter handlerAdapter = new FlowHandlerAdapter();
handlerAdapter.setFlowExecutor(this.flowExecutor());
handlerAdapter.setSaveOutputToFlashScopeOnRedirect(true);
return handlerAdapter;
}
#Bean
public ViewFactoryCreator mvcViewFactoryCreator() {
MvcViewFactoryCreator factoryCreator = new MvcViewFactoryCreator();
factoryCreator.setViewResolvers(Collections.<ViewResolver>singletonList(this.thymeleafViewResolver()));
factoryCreator.setUseSpringBeanBinding(true);
return factoryCreator;
}
#Bean
#Description("Thymeleaf AJAX view resolver for Spring WebFlow")
public AjaxThymeleafViewResolver thymeleafViewResolver() {
AjaxThymeleafViewResolver viewResolver = new AjaxThymeleafViewResolver();
viewResolver.setViewClass(FlowAjaxThymeleafView.class);
viewResolver.setTemplateEngine(this.templateEngine());
viewResolver.setCharacterEncoding("UTF-8");
return viewResolver;
}
#Bean
#Description("Thymeleaf template resolver serving HTML 5")
public ClassLoaderTemplateResolver templateResolver() {
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 engine with Spring integration")
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(this.templateResolver());
return templateEngine;
}
I always get this error No mapping found for HTTP request with URI [/static/common.css] in DispatcherServlet with name 'dispatcherServlet'
I always get this error it seems that the tags like <link rel = "stylesheet" href = "/ static / myFolder / common.css" /> are solved as html
I have issue with UTF-8 characters. I've tried many solutions, but nothing is working for me. What I have right now:
Tomcat (server.xml):
<Connector URIEncoding="UTF-8" useBodyEncodingForURI="true" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
Base configuration class:
public class HomeInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { WebSecurityConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebMvcConfiguration.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8"); // forcing UTF-8
filter.setForceEncoding(true);
return new Filter[] { filter };
}
}
WebMvcConfiguration class which contains Thymeleaf configuration:
#Bean
public ThymeleafViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setCharacterEncoding("UTF-8"); // forcing UTF-8
viewResolver.setContentType("text/html; charset=UTF-8");
viewResolver.setOrder(1);
viewResolver.setViewNames(new String[] { ".html", ".xhtml" });
return viewResolver;
}
#Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setCharacterEncoding("UTF-8"); // forcing UTF-8
templateResolver.setApplicationContext(applicationContext);
templateResolver.setPrefix("/WEB-INF/views/");
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;
}
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
registry.viewResolver(resolver);
}
WebSecurityConfig which contains the rest of the configuration:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().anonymous().antMatchers("/login**", "/*.js", "/*.css", "/*.svg").permitAll().anyRequest().authenticated()
.antMatchers("/login**").permitAll().and().formLogin().loginPage("/login").loginProcessingUrl("/login").usernameParameter("username")
.passwordParameter("password").defaultSuccessUrl("/", true).permitAll().and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login?logout").deleteCookies("JSESSIONID")
.invalidateHttpSession(true).permitAll();
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8"); // another forcing UTF-8
filter.setForceEncoding(true);
http.addFilterBefore(filter, CsrfFilter.class);
}
all html pages contain:
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
before I've added Thymeleaf and used jsp I've been able to display special characters
also checked that all files (.html) are encoded with UTF-8
Eclipse settings changed to keep everything in UTF-8
checked probably all answers on stackoverflow related to this issue and verified all higher ranked answers (including this, this and that)
checked Thymeleaf messaging solution (some stack question for that)
escaped characters \u0119 are displayed as they are - \u0119
created new project with same pom.xml, Spring/Thymeleaf configuration
And still instead of polish
ąęłźżńłó
I have
???????ó
displayed on page. Any ideas?
Unfortunatelly I don't have
web.xml
and whole configuration uses annotations. I can't control
Filter
classes order - see can use #Order annotation
Used technologies: Spring Framework 5.1.6, Spring Security 5.1.5, Thymeleaf 3.0.11, Thymeleaf Spring security4 3.0.4, Maven 4, Tomcat 9.
Unfortunatelly I have to answer my own question.
To read UTF-8 data from properties file, just use encoding property
#Component
#PropertySource(value = "classpath:config/data.properties", encoding = "UTF-8")
basically what helped was adding some additional method calls to the configureViewResolvers method:
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setCharacterEncoding("UTF-8"); // <- this was added
resolver.setForceContentType(true); // <- this was added
resolver.setContentType("text/html; charset=UTF-8"); // <- this was added
registry.viewResolver(resolver);
}
and additionaly in configure(HttpSecurity http) method I've changed the way how filter is added to this:
#Override
protected void configure(HttpSecurity http) throws Exception {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceEncoding(true);
http.authorizeRequests().anyRequest().anonymous()
.antMatchers("/login**", "/*.js", "/*.css", "/*.svg" ).permitAll()
// ... some other config
.invalidateHttpSession(true)
.permitAll()
.and()
.addFilterBefore(filter, CsrfFilter.class); // <- this was added
}
So this might seem very remedial, but have you navigated to the directory structure, right clicked the folder containing your pages, and selecting refresh?
I don't know what IDE you're using, but in the past I have had to manually go into Eclipse and refresh the package containing the static content.
If you don't do this, it won't pick up on the changes.
I using Spring 5. Have problems with encoding, like this:
ÐÐµÑ Ñакого бÑенда: 1000. ÐожалÑйÑÑа, пÑовеÑÑÑе запÑоÑ.
I tried to fix encoding this way:
#Configuration
public class AppInit extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
addEncodingFilter(servletContext);
super.onStartup(servletContext);
}
...
private void addEncodingFilter(ServletContext servletContext) {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
EnumSet<DispatcherType> dispatcherTypes
= EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ERROR);
FilterRegistration.Dynamic characterEncoding
= servletContext.addFilter("characterEncoding", characterEncodingFilter);
characterEncoding.addMappingForUrlPatterns(dispatcherTypes, true, "/*");
characterEncoding.setAsyncSupported(true);
}
}
but have no result. Please, give me ready solution how to set encoding for Spring 5.
Try using spring Beans.
#Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
encodingFilter.setEncoding("UTF-8");
encodingFilter.setForceEncoding(true);
registrationBean.setFilter(encodingFilter);
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
Solution was:
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasename("i18n/messages");
source.setDefaultEncoding("UTF-8");
return source;
}
I needed simply to set default encoding for i18n files.
I am writing a JUnit test, which should test the title of an html page. This project is a SpringBoot, Thymeleaf starter project.
HtmlPath:
private final static String HTML_PATH = "/pages/dashboard/dashboard.html";
JUnitTest:
#Test
public void shouldRenderPageTitle() throws IOException, NodeSelectorException {
Map<String,Object> model = new HashMap<>();
model.put("pageTitle", "expected title");
HtmlElements tags = testEngine.process(HTML_PATH, model);
assertThat(tags.matching("title"), isSingleElementThat(hasOnlyText("expected title")));
}
ThymeleafConfiguration
#Configuration
public class ThymeleafConfig {
#Bean
public TemplateResolver templateResolver() {
TemplateResolver templateResolver = new TemplateResolver();
templateResolver.setPrefix("/resources/templates/");
return templateResolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.addDialect(new LayoutDialect());
templateEngine.addDialect(new SpringStandardDialect());
return templateEngine;
}
#Bean
public ThymeleafViewResolver thymeleafViewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
return viewResolver;
}
}
The Error:
org.thymeleaf.exceptions.TemplateInputException: Error resolving template "/pages/dashboard/dashboard.html"
You have to use
private final static String HTML_PATH = "/pages/dashboard/dashboard"; //no ".html"
Can you try replacing this line of code
templateResolver.setPrefix("/resources/templates/");
with this one
templateResolver.setPrefix("templates/");
I'm trying to implement what Bryan Hansen taught in his spring mvc video serie for internationalization; I'm writing the same code as e does but mine does not work properly and I'm getting the following error message :
No message found under code 'student.name' for locale 'en_US'
my startup class is as follow :
public class Startup implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
//get the context :
WebApplicationContext context = this.getContext();
//creates a listener :
ContextLoaderListener listener = new ContextLoaderListener(context);
servletContext.addListener(listener);
//register as servlet :
ServletRegistration.Dynamic dispatcherServlet = servletContext.addServlet("dispatcher", new DispatcherServlet(context));
dispatcherServlet.setLoadOnStartup(1);
dispatcherServlet.addMapping("/");
}
private WebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(WebConfig.class);
return context;
}
}
and my web config class is as follow :
#Configuration
#ComponentScan(basePackages = "ga.shahab.controllers")
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry resource) {
resource.addResourceHandler("/res/**").addResourceLocations("/resources/");
resource.addResourceHandler("/app/*.js").addResourceLocations("/resources/app/");
}
// START : Internationalization I18n
#Bean
public MessageSource MessageSource() {
// ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
#Bean
public LocaleResolver localResolver() {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(Locale.ENGLISH);
return localeResolver;
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor changeInterceptor = new LocaleChangeInterceptor();
changeInterceptor.setParamName("language");
registry.addInterceptor(changeInterceptor);
}
// END : Internationalization I18n
#Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/Views/");
resolver.setSuffix(".jsp");
return resolver;
}
}
I'm using spring messages like this :
<spring:message code="student.name"></spring:message>
and the structure of my project is as follow :
1.src/main/java
2.src/main/resources
my internationalization files are in the second folder( resources )
and finally my messages file includes just one line of code :
student.name=Name
but my project does not work for internationalization.
what's wrong with my sample ?!