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:
{"value":"zażóÅÄ gÄÅlÄ jaźÅ"}
{"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.