diff --git a/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java b/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java index 29b93e01a8b5..9c486030240c 100644 --- a/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java +++ b/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.net.URLEncoder; +import java.nio.charset.Charset; import java.util.Arrays; import java.util.Enumeration; import java.util.Iterator; @@ -196,6 +197,14 @@ public byte[] getContentAsByteArray() { return this.cachedContent.toByteArray(); } + /** + * Return the cached request content as a String. The Charset used to decode + * the cached content is the same as returned by getCharacterEncoding. + */ + public String getContentAsString() { + return this.cachedContent.toString(Charset.forName(getCharacterEncoding())); + } + /** * Template method for handling a content overflow: specifically, a request * body being read that exceeds the specified content cache limit. diff --git a/spring-web/src/test/java/org/springframework/web/util/ContentCachingRequestWrapperTests.java b/spring-web/src/test/java/org/springframework/web/util/ContentCachingRequestWrapperTests.java index 7a749493ce43..641ab4a10c73 100644 --- a/spring-web/src/test/java/org/springframework/web/util/ContentCachingRequestWrapperTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/ContentCachingRequestWrapperTests.java @@ -16,13 +16,13 @@ package org.springframework.web.util; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import org.junit.jupiter.api.Test; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.util.FileCopyUtils; import org.springframework.web.testfixture.servlet.MockHttpServletRequest; import static org.assertj.core.api.Assertions.assertThat; @@ -35,7 +35,7 @@ public class ContentCachingRequestWrapperTests { protected static final String FORM_CONTENT_TYPE = MediaType.APPLICATION_FORM_URLENCODED_VALUE; - protected static final String CHARSET = StandardCharsets.UTF_8.name(); + protected static final Charset CHARSET = StandardCharsets.UTF_8; protected static final String GET = HttpMethod.GET.name(); @@ -49,30 +49,32 @@ public class ContentCachingRequestWrapperTests { @Test void cachedContent() throws Exception { this.request.setMethod(GET); - this.request.setCharacterEncoding(CHARSET); + this.request.setCharacterEncoding(CHARSET.name()); this.request.setContent("Hello World".getBytes(CHARSET)); ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(this.request); - byte[] response = FileCopyUtils.copyToByteArray(wrapper.getInputStream()); + byte[] response = wrapper.getInputStream().readAllBytes(); assertThat(wrapper.getContentAsByteArray()).isEqualTo(response); + assertThat(wrapper.getContentAsString()).isEqualTo("Hello World"); } @Test void cachedContentWithLimit() throws Exception { this.request.setMethod(GET); - this.request.setCharacterEncoding(CHARSET); + this.request.setCharacterEncoding(CHARSET.name()); this.request.setContent("Hello World".getBytes(CHARSET)); ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(this.request, CONTENT_CACHE_LIMIT); - byte[] response = FileCopyUtils.copyToByteArray(wrapper.getInputStream()); + byte[] response = wrapper.getInputStream().readAllBytes(); assertThat(response).isEqualTo("Hello World".getBytes(CHARSET)); assertThat(wrapper.getContentAsByteArray()).isEqualTo("Hel".getBytes(CHARSET)); + assertThat(wrapper.getContentAsString()).isEqualTo("Hel"); } @Test void cachedContentWithOverflow() throws Exception { this.request.setMethod(GET); - this.request.setCharacterEncoding(CHARSET); + this.request.setCharacterEncoding(CHARSET.name()); this.request.setContent("Hello World".getBytes(CHARSET)); ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(this.request, CONTENT_CACHE_LIMIT) { @@ -82,8 +84,7 @@ protected void handleContentOverflow(int contentCacheLimit) { } }; - assertThatIllegalStateException().isThrownBy(() -> - FileCopyUtils.copyToByteArray(wrapper.getInputStream())) + assertThatIllegalStateException().isThrownBy(() -> wrapper.getInputStream().readAllBytes()) .withMessage("3"); } @@ -91,7 +92,7 @@ protected void handleContentOverflow(int contentCacheLimit) { void requestParams() throws Exception { this.request.setMethod(POST); this.request.setContentType(FORM_CONTENT_TYPE); - this.request.setCharacterEncoding(CHARSET); + this.request.setCharacterEncoding(CHARSET.name()); this.request.setParameter("first", "value"); this.request.setParameter("second", "foo", "bar"); @@ -99,22 +100,24 @@ void requestParams() throws Exception { // getting request parameters will consume the request body assertThat(wrapper.getParameterMap().isEmpty()).isFalse(); assertThat(new String(wrapper.getContentAsByteArray())).isEqualTo("first=value&second=foo&second=bar"); + assertThat(wrapper.getContentAsString()).isEqualTo("first=value&second=foo&second=bar"); // SPR-12810 : inputstream body should be consumed - assertThat(new String(FileCopyUtils.copyToByteArray(wrapper.getInputStream()))).isEmpty(); + assertThat(new String(wrapper.getInputStream().readAllBytes())).isEmpty(); } @Test // SPR-12810 void inputStreamFormPostRequest() throws Exception { this.request.setMethod(POST); this.request.setContentType(FORM_CONTENT_TYPE); - this.request.setCharacterEncoding(CHARSET); + this.request.setCharacterEncoding(CHARSET.name()); this.request.setParameter("first", "value"); this.request.setParameter("second", "foo", "bar"); ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(this.request); - byte[] response = FileCopyUtils.copyToByteArray(wrapper.getInputStream()); + byte[] response = wrapper.getInputStream().readAllBytes(); assertThat(wrapper.getContentAsByteArray()).isEqualTo(response); + assertThat(wrapper.getContentAsString()).isEqualTo(new String(response, CHARSET)); } }