12

I am updating spring-boot from 1.3.6 to 2.1.3 and while before responses had content type application/json;charset=UTF-8, now I am getting a charset of iso-8859-1.

I would like to have utf 8.

My controller looks like this:

@Controller
public class MyController {
    @RequestMapping(value={"/myService/{serviceId}"}, method=RequestMethod.POST, consumes="application/json")
    public ResponseEntity<Void> handlePostServiceId(final InputStream requestInputStream,
            @PathVariable String serviceId,
            final HttpServletRequest servletRequest,) {
       <$businessLogic>
       return new ResponseEntity<>(new HttpHeaders(), HttpStatus.ACCEPTED);
}

I can get it to return utf-8 if I include produces= MediaType.APPLICATION_JSON_UTF8_VALUE in my @RequestMapping but I would like to only have to set that once, rather than for every single API.

I also tried adding

@Override
    public void configureContentNegotiation(
         ContentNegotiationConfigurer configurer) {
         configurer.defaultContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
    }

to my WebMvcConfigurer as suggested here: https://stackoverflow.com/a/25275291/2855921 but that broke my availability api which consumes plain/text content type.

I also ensured that my request was UTF-8, so it is not just mirroring back the format I gave.

Any ideas on how I can set the charset to be UTF-8 for the entire project?

pdewilde
  • 176
  • 1
  • 1
  • 10
  • You can set `produces` at class level which will get applied to all the api's in that controller class. – ravinikam Apr 11 '19 at 23:02
  • I really don't know what happened. It turns out it was just two mappings that didn't work properly. I tried both the application.properties method as well as using a CharacterEncodingFilter, but neither fixed the issue. The two offending mappings were the only ones which explicitly says produces, but they were set to MediaType.APPLICATION_JSON_VALUE which is just "application/json", and trying that in other mappings gave back utf-8. I ended up just setting those two to MediaType.APPLICATION_JSON_UTF8_VALUE manually and moving on, as nothing else worked. – pdewilde Apr 12 '19 at 19:42
  • Someone may have a different issue and find this helpful: https://stackoverflow.com/questions/24054648/how-to-configure-characterencodingfilter-in-springboot – pdewilde Apr 12 '19 at 19:50
  • Did you find a way – Mohit Oct 15 '19 at 10:53
  • @Mohit see my answer – oshatrk Oct 29 '19 at 10:39
  • It's unclear if this was solved, but if you were reading from a messages.properties-file like me, this may fix it: https://stackoverflow.com/a/28114437/483113 – sjngm Apr 13 '23 at 22:48

2 Answers2

19

Add the below properties to the application.properties file:

For Spring Boot 1.x

# Charset of HTTP requests and responses. Added to the "Content-Type" 
# header if not set explicitly.
spring.http.encoding.charset=UTF-8
# Enable http encoding support.
spring.http.encoding.enabled=true
# Force the encoding to the configured charset on HTTP requests and responses.
spring.http.encoding.force=true

Source: https://docs.spring.io/spring-boot/docs/1.5.22.RELEASE/reference/html/common-application-properties.html

For Spring Boot 2.x

server.servlet.encoding.charset=UTF-8
server.servlet.encoding.force-response=true

Source: https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#server.servlet.encoding.charset

Milanka
  • 1,742
  • 19
  • 15
Bishal Jaiswal
  • 1,684
  • 13
  • 15
7

If you're using default object mapper (Jackson) then the encoding can be forced with this simple configuration:

    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
        jsonConverter.setDefaultCharset(StandardCharsets.UTF_8);
        return jsonConverter;
    }

Here the MappingJackson2HttpMessageConverter() constructor uses public Jackson2ObjectMapperBuilder class to set default parameters for an object mapper.

For another object mapper (Gson or Jsonb) you can look into AllEncompassingFormHttpMessageConverter() constructor.

Note also MediaType.APPLICATION_JSON_UTF8 was deprecated in favor of MediaType.APPLICATION_JSON since Spring 5.2. So in tests I prefer to use contentTypeCompatibleWith(...) instead of contentType(..._UTF8):

        MvcResult result = mockMvc.perform(get("/api/resource"))
                .andDo(print())
                .andExpect(status().isOk())
                // .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
                .andReturn();

Links:

More examples with MappingJackson2HttpMessageConverter:

Community
  • 1
  • 1
oshatrk
  • 499
  • 3
  • 14
  • It doesn’t work for me. In my case, everything is working fine for English characters. But if I try to send some french or Spanish characters then it's throwing an error – Deepak Kumar May 22 '21 at 11:48
  • @DeepakKumar It's unclear if this was solved for you, but if you were reading from a messages.properties-file like me, this may fix it: https://stackoverflow.com/a/28114437/483113 – sjngm Apr 13 '23 at 22:49