Skip to content

Commit

Permalink
Use UTF-8 with JSON in MockHttpServletResponse
Browse files Browse the repository at this point in the history
This commit makes MockHttpServletResponse consistent with the other
parts of the framework where the body of a response is read as an UTF-8
String when the content type is application/json or similar, overriding
the ISO-8859-1 default Servlet encoding.

Closes gh-33019
  • Loading branch information
sdeleuze committed Jun 19, 2024
1 parent 2116d71 commit 1d363e5
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
Expand Down Expand Up @@ -72,6 +73,8 @@ public class MockHttpServletResponse implements HttpServletResponse {

private static final TimeZone GMT = TimeZone.getTimeZone("GMT");

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


//---------------------------------------------------------------------
// ServletResponse properties
Expand Down Expand Up @@ -348,6 +351,10 @@ public void setContentType(@Nullable String contentType) {
if (mediaType.getCharset() != null) {
setExplicitCharacterEncoding(mediaType.getCharset().name());
}
else if (mediaType.isCompatibleWith(MediaType.APPLICATION_JSON) ||
mediaType.isCompatibleWith(APPLICATION_PLUS_JSON)) {
this.characterEncoding = StandardCharsets.UTF_8.name();
}
}
catch (Exception ex) {
// Try to get charset value anyway
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -257,7 +257,7 @@ public ResultMatcher json(String jsonContent, JsonCompareMode compareMode) {
*/
public ResultMatcher json(String jsonContent, JsonComparator comparator) {
return result -> {
String content = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
String content = result.getResponse().getContentAsString();
comparator.assertIsMatch(jsonContent, content);
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package org.springframework.test.web.servlet.result;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;

import com.jayway.jsonpath.JsonPath;
import org.hamcrest.Matcher;
Expand Down Expand Up @@ -238,7 +237,7 @@ public ResultMatcher isMap() {
}

private String getContent(MvcResult result) throws UnsupportedEncodingException {
String content = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
String content = result.getResponse().getContentAsString();
if (StringUtils.hasLength(this.prefix)) {
try {
String reason = String.format("Expected a JSON payload prefixed with \"%s\" but found: %s",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,7 +16,6 @@

package org.springframework.test.web.servlet.result;

import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Map;
Expand All @@ -28,7 +27,6 @@

import org.springframework.core.style.ToStringCreator;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
Expand Down Expand Up @@ -250,9 +248,7 @@ protected void printResponse(MockHttpServletResponse response) throws Exception
this.printer.printValue("Error message", response.getErrorMessage());
this.printer.printValue("Headers", getResponseHeaders(response));
this.printer.printValue("Content type", response.getContentType());
String body = (MediaType.APPLICATION_JSON_VALUE.equals(response.getContentType()) ?
response.getContentAsString(StandardCharsets.UTF_8) : response.getContentAsString());
this.printer.printValue("Body", body);
this.printer.printValue("Body", response.getContentAsString());
this.printer.printValue("Forwarded URL", response.getForwardedUrl());
this.printer.printValue("Redirected URL", response.getRedirectedUrl());
printCookies(response.getCookies());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import org.springframework.http.MediaType;
import org.springframework.web.util.WebUtils;

import static org.assertj.core.api.Assertions.assertThat;
Expand Down Expand Up @@ -620,4 +621,12 @@ void resetResetsCharset() {
assertThat(contentTypeHeader).isEqualTo("text/plain");
}

@Test // gh-33019
void contentAsStringEncodingWithJson() throws IOException {
String content = "{\"name\": \"Jürgen\"}";
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.getWriter().write(content);
assertThat(response.getContentAsString()).isEqualTo(content);
}

}

0 comments on commit 1d363e5

Please sign in to comment.