How to overwrite StringHttpMessageConverter DEFAULT_CHARSET to use UTF8 in spring 4

I am trying to make spring @ResponseBody always return utf-8. But I can’t take so long. The problem occurs when I return a simple text response:

@RequestMapping(value="/test", method=RequestMethod.PUT) @ResponseBody public String ajaxTest() { return "Characters test: ęółąśżźćń"; } 

Does every Polish character (ęółąśżźćń) go to ?

And on the webpage I get this line: Characters test: ? ??????? instead of Characters test: ęółąśżźćń

I don’t know what I am missing.

I added a custome bean to the public class WebAppConfig extends WebMvcConfigurerAdapter {} This looks like this:

 @Bean public HttpMessageConverter<String> responseBodyConverter() { StringHttpMessageConverter converter = new StringHttpMessageConverter(); converter.setSupportedMediaTypes(Arrays.asList(new MediaType("text", "plain", Charset.forName("UTF-8")))); return converter; } 

Instructions taken from https://jira.spring.io/browse/SPR-9099

But that will not work. I can see in firefox and chrome that the return value is in utf-8: enter image description here


Spring version: 4.1.1.RELEASE

Web Application Configuration Class:

 package com.derp.common.init; import java.nio.charset.Charset; import java.util.Arrays; import java.util.List; import java.util.Properties; import javax.annotation.Resource; import javax.sql.DataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.orm.hibernate4.HibernateTransactionManager; import org.springframework.orm.hibernate4.LocalSessionFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; //import com.derp.common.wicketView.HomePage; @Configuration @ComponentScan("com.derp") @EnableWebMvc @EnableTransactionManagement @PropertySource("classpath:application.properties") public class WebAppConfig extends WebMvcConfigurerAdapter { private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver"; private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password"; private static final String PROPERTY_NAME_DATABASE_URL = "db.url"; private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username"; private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect"; private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql"; private static final String PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO = "hibernate.hbm2ddl.auto"; private static final String PROPERTY_NAME_HIBERNATE_CONNECTION_CHARSET = "hibernate.connection.CharSet"; private static final String PROPERTY_NAME_HIBERNATE_CONNECTION_CHARACTERENCODING = "hibernate.connection.characterEncoding"; private static final String PROPERTY_NAME_HIBERNATE_CONNECTION_USEUNICODE = "hibernate.connection.useUnicode"; private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_SERVICES = "services.entitymanager.packages.to.scan"; private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_COMMON = "common.entitymanager.packages.to.scan"; private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_CMS = "cms.entitymanager.packages.to.scan"; private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_PROCEDURE = "procedure.entitymanager.packages.to.scan"; @Resource private Environment env; @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER)); dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL)); dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME)); dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD)); return dataSource; } @Bean public LocalSessionFactoryBean sessionFactory() { LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean(); sessionFactoryBean.setDataSource(dataSource()); //sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN)); sessionFactoryBean.setPackagesToScan(new String[] { env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_SERVICES), env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_COMMON), env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_CMS), env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_PROCEDURE) }); sessionFactoryBean.setHibernateProperties(hibProperties()); return sessionFactoryBean; } private Properties hibProperties() { Properties properties = new Properties(); properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT)); properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL)); properties.put(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO)); properties.put(PROPERTY_NAME_HIBERNATE_CONNECTION_CHARSET, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CONNECTION_CHARSET)); properties.put(PROPERTY_NAME_HIBERNATE_CONNECTION_CHARACTERENCODING, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CONNECTION_CHARACTERENCODING)); properties.put(PROPERTY_NAME_HIBERNATE_CONNECTION_USEUNICODE, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CONNECTION_USEUNICODE)); properties.put("jadira.usertype.autoRegisterUserTypes", "true"); return properties; } @Bean public HibernateTransactionManager transactionManager() { HibernateTransactionManager transactionManager = new HibernateTransactionManager(); transactionManager.setSessionFactory(sessionFactory().getObject()); return transactionManager; } @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { // Simple strategy: only path extension is taken into account configurer.favorPathExtension(true). ignoreAcceptHeader(true). useJaf(false). defaultContentType(MediaType.TEXT_HTML). mediaType("html", MediaType.TEXT_HTML). mediaType("xml", MediaType.APPLICATION_XML). mediaType("json", MediaType.APPLICATION_JSON); } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/img/**").addResourceLocations("/WEB-INF/img/*"); registry.addResourceHandler("/css/**").addResourceLocations("/WEB-INF/css/*"); registry.addResourceHandler("/js/**").addResourceLocations("/WEB-INF/js/*"); registry.addResourceHandler("/lib/**").addResourceLocations("/WEB-INF/lib/*"); } @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { super.configureMessageConverters(converters); converters.add(responseBodyConverter()); } @Bean public HttpMessageConverter<String> responseBodyConverter() { StringHttpMessageConverter converter = new StringHttpMessageConverter(); converter.setSupportedMediaTypes(Arrays.asList(new MediaType("text", "plain", Charset.forName("UTF-8")))); return converter; } } 

Application Initializer:

 package com.derp.common.init; import java.nio.charset.Charset; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration.Dynamic; import org.springframework.http.MediaType; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.filter.CharacterEncodingFilter; import org.springframework.web.filter.HiddenHttpMethodFilter; import org.springframework.web.servlet.DispatcherServlet; public class Initializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(WebAppConfig.class); ctx.register(ThymeleafConfig.class); servletContext.addListener(new ContextLoaderListener(ctx)); ctx.setServletContext(servletContext); Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx)); servlet.addMapping("/"); servlet.setAsyncSupported(true); servlet.setLoadOnStartup(1); // Allow to use Put and Delete method for REST architecture registerCharachterEncodingFilter(servletContext); registerHiddenFieldFilter(servletContext); } private void registerCharachterEncodingFilter(ServletContext aContext) { CharacterEncodingFilter cef = new CharacterEncodingFilter(); cef.setForceEncoding(true); cef.setEncoding("UTF-8"); aContext.addFilter("charachterEncodingFilter", cef).addMappingForUrlPatterns(null ,true, "/*"); } private void registerHiddenFieldFilter(ServletContext aContext) { aContext.addFilter("hiddenHttpMethodFilter", new HiddenHttpMethodFilter()).addMappingForUrlPatterns(null ,true, "/*"); } } 

Java script / jquery ajax call

  $('h1').click(function() { $.ajax({ type: "PUT", url: "/derp/procedury/test", data: "none", success: function (response, status, xhr) { showNotifications(status, xhr.responseText); }, error: function (response, status, xhr) { showNotifications('error', JSON.stringify(response)); showNotifications('error', status); showNotifications('error', xhr); } }); }); 

Please, help.

+5
source share
2 answers

The Network tab displays

 text/html;charset=UTF-8 

which is not what you tuned for it

 converter.setSupportedMediaTypes(Arrays.asList(new MediaType("text", "plain", Charset.forName("UTF-8")))); 

It seems your custom HttpMessageConverter bean is not registering. Add this to the WebAppConfig class

 @Override protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) { super.configureMessageConverters(converters); converters.add(responseBodyConverter()); } 

You should see that your answer contains

 Content-Type:"text/plain;charset=UTF-8" 

I can’t explain why your tab on the browser network displayed UTF-8 , but couldn’t parse or display it. This works great for me.

+5
source

The problem is that StringHttpMessageConverter defaults to ISO-8859-1. You need to either set the default value for UTF-8, as shown below:

  @Bean public HttpMessageConverter<String> responseBodyConverter() { StringHttpMessageConverter converter = new StringHttpMessageConverter(StandardCharsets.UTF_8); converter.setSupportedMediaTypes(Arrays.asList(new MediaType("text", "plain", Charset.forName("UTF-8")))); return converter; } 

Or ask the client to specify exactly what they want with the Accept heading, that is: Accept: text/plain;charset="UTF-8" .

+1
source

Source: https://habr.com/ru/post/1209713/


All Articles