diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java index f18564333006..77c5f4c11afa 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java @@ -23,6 +23,7 @@ import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; +import java.nio.charset.Charset; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -204,11 +205,32 @@ public byte[] getContentAsByteArray() { return this.content.toByteArray(); } + /** + * Get the content of the response body as a {@code String}, using the configured + * {@linkplain #getCharacterEncoding character encoding}. + * @return the content as a {@code String} + * @throws UnsupportedEncodingException if the character encoding is not supported + * @see #getContentAsString(Charset) + */ public String getContentAsString() throws UnsupportedEncodingException { return (this.characterEncoding != null ? this.content.toString(this.characterEncoding) : this.content.toString()); } + /** + * Get the content of the response body as a {@code String}, using the provided + * {@code fallbackCharset} if no charset has been explicitly defined, else using + * using the configured {@linkplain #getCharacterEncoding character encoding}. + * @return the content as a {@code String} + * @throws UnsupportedEncodingException if the character encoding is not supported + * @see #getContentAsString() + */ + public String getContentAsString(Charset fallbackCharset) throws UnsupportedEncodingException { + return isCharset() ? + this.content.toString(this.characterEncoding) : + this.content.toString(fallbackCharset.name()); + } + @Override public void setContentLength(int contentLength) { this.contentLength = contentLength; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/result/JsonPathResultMatchers.java b/spring-test/src/main/java/org/springframework/test/web/servlet/result/JsonPathResultMatchers.java index 853e9ca11133..869e3200dc51 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/result/JsonPathResultMatchers.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/result/JsonPathResultMatchers.java @@ -17,6 +17,7 @@ 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; @@ -235,7 +236,7 @@ public ResultMatcher isMap() { } private String getContent(MvcResult result) throws UnsupportedEncodingException { - String content = result.getResponse().getContentAsString(); + String content = result.getResponse().getContentAsString(StandardCharsets.UTF_8); if (StringUtils.hasLength(this.prefix)) { try { String reason = String.format("Expected a JSON payload prefixed with \"%s\" but found: %s", diff --git a/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java b/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java index 1c36c1f3be37..9063991058d6 100644 --- a/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java +++ b/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java @@ -17,6 +17,7 @@ package org.springframework.mock.web; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collection; import javax.servlet.http.Cookie; @@ -39,6 +40,7 @@ * @author Rob Winch * @author Sam Brannen * @author Brian Clozel + * @author Sebastien Deleuze * @since 19.02.2006 */ public class MockHttpServletResponseTests { @@ -238,10 +240,11 @@ public void servletWriterCommittedOnWriterClose() throws IOException { assertThat(response.getContentAsByteArray().length).isEqualTo(1); } - @Test - public void servletWriterAutoFlushedForString() throws IOException { - response.getWriter().write("X"); - assertThat(response.getContentAsString()).isEqualTo("X"); + @Test // gh-23219 + public void contentAsUtf8() throws IOException { + String content = "Příliš žluťoučký kůň úpěl ďábelské ódy"; + response.getOutputStream().write(content.getBytes(StandardCharsets.UTF_8)); + assertThat(response.getContentAsString(StandardCharsets.UTF_8)).isEqualTo(content); } @Test @@ -256,6 +259,12 @@ public void servletWriterAutoFlushedForCharArray() throws IOException { assertThat(response.getContentAsString()).isEqualTo("XY"); } + @Test + public void servletWriterAutoFlushedForString() throws IOException { + response.getWriter().write("X"); + assertThat(response.getContentAsString()).isEqualTo("X"); + } + @Test public void sendRedirect() throws IOException { String redirectUrl = "/redirect"; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/result/JsonPathResultMatchersTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/result/JsonPathResultMatchersTests.java index cfc14d6153d0..05ec75dd65b0 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/result/JsonPathResultMatchersTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/result/JsonPathResultMatchersTests.java @@ -16,6 +16,8 @@ package org.springframework.test.web.servlet.result; +import java.nio.charset.StandardCharsets; + import org.hamcrest.Matchers; import org.junit.Test; @@ -31,11 +33,13 @@ * @author Craig Andrews * @author Sam Brannen * @author Brian Clozel + * @author Sebastien Deleuze */ public class JsonPathResultMatchersTests { private static final String RESPONSE_CONTENT = "{" + // "'str': 'foo', " + // + "'utf8Str': 'Příliš', " + // "'num': 5, " + // "'bool': true, " + // "'arr': [42], " + // @@ -51,7 +55,7 @@ public class JsonPathResultMatchersTests { try { MockHttpServletResponse response = new MockHttpServletResponse(); response.addHeader("Content-Type", "application/json"); - response.getWriter().print(new String(RESPONSE_CONTENT.getBytes("ISO-8859-1"))); + response.getOutputStream().write(RESPONSE_CONTENT.getBytes(StandardCharsets.UTF_8)); stubMvcResult = new StubMvcResult(null, null, null, null, null, null, response); } catch (Exception e) { @@ -70,6 +74,11 @@ public void valueWithDirectMatch() throws Exception { new JsonPathResultMatchers("$.str").value("foo").match(stubMvcResult); } + @Test // gh-23219 + public void utf8ValueWithDirectMatch() throws Exception { + new JsonPathResultMatchers("$.utf8Str").value("Příliš").match(stubMvcResult); + } + @Test // SPR-16587 public void valueWithNumberConversion() throws Exception { new JsonPathResultMatchers("$.num").value(5.0f).match(stubMvcResult);