Skip to content

Commit

Permalink
Use UTF-8 for application/*+json
Browse files Browse the repository at this point in the history
This commit makes sure that the StringHttpMessageConverter reads
input with "application/*+json" as Content-Type with the UTF-8
character set.

Closes spring-projectsgh-25328
  • Loading branch information
poutsma authored and xcl(徐程林) committed Aug 16, 2020
1 parent 9f3017d commit 780ffb8
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
Expand Up @@ -43,6 +43,8 @@
*/
public class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> {

private static final MediaType APPLICATION_PLUS_JSON = new MediaType("application", "*+json");

/**
* The default charset used by the converter.
*/
Expand Down Expand Up @@ -104,7 +106,9 @@ protected Long getContentLength(String str, @Nullable MediaType contentType) {
@Override
protected void addDefaultHeaders(HttpHeaders headers, String s, @Nullable MediaType type) throws IOException {
if (headers.getContentType() == null ) {
if (type != null && type.isConcrete() && type.isCompatibleWith(MediaType.APPLICATION_JSON)) {
if (type != null && type.isConcrete() &&
(type.isCompatibleWith(MediaType.APPLICATION_JSON) ||
type.isCompatibleWith(APPLICATION_PLUS_JSON))) {
// Prevent charset parameter for JSON..
headers.setContentType(type);
}
Expand Down Expand Up @@ -142,7 +146,9 @@ private Charset getContentTypeCharset(@Nullable MediaType contentType) {
if (contentType != null && contentType.getCharset() != null) {
return contentType.getCharset();
}
else if (contentType != null && contentType.isCompatibleWith(MediaType.APPLICATION_JSON)) {
else if (contentType != null &&
(contentType.isCompatibleWith(MediaType.APPLICATION_JSON) ||
contentType.isCompatibleWith(APPLICATION_PLUS_JSON))) {
// Matching to AbstractJackson2HttpMessageConverter#DEFAULT_CHARSET
return StandardCharsets.UTF_8;
}
Expand Down
Expand Up @@ -80,6 +80,16 @@ public void readJson() throws IOException {
assertThat(result).as("Invalid result").isEqualTo(body);
}

@Test // gh-25328
public void readJsonApi() throws IOException {
String body = "{\"result\":\"\u0414\u0410\"}";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes(StandardCharsets.UTF_8));
inputMessage.getHeaders().setContentType(new MediaType("application", "vnd.api.v1+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";
Expand All @@ -94,7 +104,7 @@ public void writeDefaultCharset() throws IOException {

@Test // gh-24123
public void writeJson() throws IOException {
String body = "{\"foo\":\"bar\"}";
String body = "{\"føø\":\"bår\"}";
this.converter.write(body, MediaType.APPLICATION_JSON, this.outputMessage);

HttpHeaders headers = this.outputMessage.getHeaders();
Expand All @@ -104,6 +114,19 @@ public void writeJson() throws IOException {
assertThat(headers.getAcceptCharset().isEmpty()).isTrue();
}

@Test // gh-25328
public void writeJsonApi() throws IOException {
String body = "{\"føø\":\"bår\"}";
MediaType contentType = new MediaType("application", "vnd.api.v1+json");
this.converter.write(body, contentType, this.outputMessage);

HttpHeaders headers = this.outputMessage.getHeaders();
assertThat(this.outputMessage.getBodyAsString(StandardCharsets.UTF_8)).isEqualTo(body);
assertThat(headers.getContentType()).isEqualTo(contentType);
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";
Expand Down

0 comments on commit 780ffb8

Please sign in to comment.