JSON charset handling in StringHttpMessageConverter

This commit restores the interpretation of JSON as UTF-8 by default that
was removed in #bc205e0 and also ensures a charset is not appended
automatically to "application/json".

Closes gh-24123
This commit is contained in:
Rossen Stoyanchev 2019-12-10 16:37:31 +00:00
parent 70a0c93d69
commit 9b30d46ff4
3 changed files with 40 additions and 2 deletions

View File

@ -100,6 +100,18 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
return (long) str.getBytes(charset).length;
}
@Override
protected void addDefaultHeaders(HttpHeaders headers, String s, @Nullable MediaType mediaType) throws IOException {
if (headers.getContentType() == null ) {
if (mediaType != null && mediaType.isCompatibleWith(MediaType.APPLICATION_JSON)) {
// Prevent charset parameter for JSON..
headers.setContentType(mediaType);
}
}
super.addDefaultHeaders(headers, s, mediaType);
}
@Override
protected void writeInternal(String str, HttpOutputMessage outputMessage) throws IOException {
HttpHeaders headers = outputMessage.getHeaders();
@ -130,6 +142,10 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
if (contentType != null && contentType.getCharset() != null) {
return contentType.getCharset();
}
else if (contentType != null && contentType.isCompatibleWith(MediaType.APPLICATION_JSON)) {
// Matching to AbstractJackson2HttpMessageConverter#DEFAULT_CHARSET
return StandardCharsets.UTF_8;
}
else {
Charset charset = getDefaultCharset();
Assert.state(charset != null, "No default charset");

View File

@ -70,6 +70,16 @@ public class StringHttpMessageConverterTests {
assertThat(result).as("Invalid result").isEqualTo(body);
}
@Test // gh-24123
public void readJson() throws IOException {
String body = "{\"result\":\"\u0414\u0410\"}";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes(StandardCharsets.UTF_8));
inputMessage.getHeaders().setContentType(MediaType.APPLICATION_JSON);
String result = this.converter.read(String.class, inputMessage);
assertThat(result).as("Invalid result").isEqualTo(body);
}
@Test
public void writeDefaultCharset() throws IOException {
String body = "H\u00e9llo W\u00f6rld";
@ -82,6 +92,18 @@ public class StringHttpMessageConverterTests {
assertThat(headers.getAcceptCharset().isEmpty()).isTrue();
}
@Test // gh-24123
public void writeJson() throws IOException {
String body = "{\"foo\":\"bar\"}";
this.converter.write(body, MediaType.APPLICATION_JSON, this.outputMessage);
HttpHeaders headers = this.outputMessage.getHeaders();
assertThat(this.outputMessage.getBodyAsString(StandardCharsets.UTF_8)).isEqualTo(body);
assertThat(headers.getContentType()).isEqualTo(MediaType.APPLICATION_JSON);
assertThat(headers.getContentLength()).isEqualTo(body.getBytes(StandardCharsets.UTF_8).length);
assertThat(headers.getAcceptCharset().isEmpty()).isTrue();
}
@Test
public void writeUTF8() throws IOException {
String body = "H\u00e9llo W\u00f6rld";

View File

@ -1011,7 +1011,7 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
request.addHeader("Accept", "application/json, text/javascript, */*");
MockHttpServletResponse response = new MockHttpServletResponse();
getServlet().service(request, response);
assertThat(response.getHeader("Content-Type")).as("Invalid content-type").isEqualTo("application/json;charset=ISO-8859-1");
assertThat(response.getHeader("Content-Type")).as("Invalid content-type").isEqualTo("application/json");
}
@Test
@ -1548,7 +1548,7 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
getServlet().service(request, response);
assertThat(response.getStatus()).isEqualTo(200);
assertThat(response.getHeader("Content-Type")).isEqualTo("application/json;charset=ISO-8859-1");
assertThat(response.getHeader("Content-Type")).isEqualTo("application/json");
assertThat(response.getContentAsString()).isEqualTo("homeJson");
}