Affects: 5.2.0 and later

RestTemplate reads JSON body as ISO-8859-1 instead of UTF-8 when content type has +json suffix, e.g. application/vnd.api.v1+json, and responseType is set to String. Note that UTF-8 is chosen for application/json content-type.

This behaviour exists in Spring for a long time, but has now larger impact after Spring MVC applications stopped setting ;charset=utf-8 (#22788). We started observing it in multiple places of our ~500 Spring Boot microservices ecosystem after upgrades to Spring Boot 2.2.0 and later.

Details

Let's consider a controller:

@RestController
class Controller {

    @GetMapping(path = "/hello", produces = "application/vnd.api.v1+json")
    Hello hello() {
        return new Hello("zażółć gęślą jaźń");
    }

    static class Hello {
        private final String value;

        @JsonCreator
        Hello(@JsonProperty("value") String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }
    }
}

Now let's call this controller in 2 different ways:

public static void main(String[] args) {
    new RestTemplate().exchange(
        "http://localhost:8080/hello", HttpMethod.GET, entityWithAcceptJsonSuffix(), String.class
    ).getBody();  // 1

    new RestTemplate().exchange(
        "http://localhost:8080/hello", HttpMethod.GET, entityWithAcceptJsonSuffix(), Hello.class
    ).getBody();  // 2
}

private static HttpEntity<?> entityWithAcceptJsonSuffix() {
        HttpHeaders headers = new HttpHeaders();
        headers.set("accept", "application/vnd.api.v1+json");
        return new HttpEntity<>(headers);
}

Actual behaviour

The body read in the setup above is:

  1. {"value":"zażółć gęślą jaźń"}
  2. {"value":"zażółć gęślą jaźń"}

Expected behaviour

Both of the above should be read as {"value":"zażółć gęślą jaźń"}.

From what I understand +json suffix content types, e.g. application/vnd.api.v1+json, should be interpreted as UTF-8 by default (RFC6839).

Comment From: poutsma

This is now fixed.