javaspring-bootspring-mvcjacksonspring-test

MockMvc no longer handles UTF-8 characters with Spring Boot 2.2.0.RELEASE


After I upgraded to the newly released 2.2.0.RELEASE version of Spring Boot some of my tests failed. It appears that the MediaType.APPLICATION_JSON_UTF8 has been deprecated and is no longer returned as default content type from controller methods that do not specify the content type explicitly.

Test code like

String content = mockMvc.perform(get("/some-api")
            .contentType(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
            .andReturn()
            .getResponse()
            .getContentAsString();

suddenly did not work anymore as the content type was mismatched as shown below

java.lang.AssertionError: Content type 
Expected :application/json;charset=UTF-8
Actual   :application/json

Changing the code to .andExpect(content().contentType(MediaType.APPLICATION_JSON)) resolved the issue for now.

But now when comparing content to the expected serialized object there is still a mismatch if there are any special characters in the object. It appears that the .getContentAsString() method does not make use of the UTF-8 character encoding by default (any more).

java.lang.AssertionError: Response content expected:<[{"description":"Er hörte leise Schritte hinter sich."}]> but was:<[{"description":"Er hörte leise Schritte hinter sich."}]>
Expected :[{"description":"Er hörte leise Schritte hinter sich."}]
Actual   :[{"description":"Er hörte leise Schritte hinter sich."}]

How can I get content in UTF-8 encoding?


Solution

  • Yes. This is problem from 2.2.0 spring-boot. They set deprecation for default charset encoding.

    .getContentAsString(StandardCharsets.UTF_8) - good but in any response would be populated ISO 8859-1 by default.

    In my project I updated current created converter:

    @Configuration
    public class SpringConfig implements WebMvcConfigurer {
    
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            converters.stream()
                .filter(converter -> converter instanceof MappingJackson2HttpMessageConverter)
                .findFirst()
                .ifPresent(converter -> ((MappingJackson2HttpMessageConverter) converter).setDefaultCharset(UTF_8));
        }
    ...