Browse Source

Introduce toString(Charset) in FastByteArrayOutputStream

This commit introduces a toString() overload in
FastByteArrayOutputStream that accepts a Charset in order to mirror the
method that was introduced in ByteArrayOutputStream in JDK 10,
including a special case for when a single buffer is in use internally
to avoid the need to resize.

This commit also updates getContentAsString() in
ContentCachingRequestWrapper to use this new toString(Charset) method.

Closes gh-31737
pull/31741/head
Patrick Strawderman 2 years ago committed by Sam Brannen
parent
commit
7cdacf3083
  1. 20
      spring-core/src/main/java/org/springframework/util/FastByteArrayOutputStream.java
  2. 18
      spring-core/src/test/java/org/springframework/util/FastByteArrayOutputStreamTests.java
  3. 2
      spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java

20
spring-core/src/main/java/org/springframework/util/FastByteArrayOutputStream.java

@ -19,6 +19,7 @@ package org.springframework.util; @@ -19,6 +19,7 @@ package org.springframework.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.util.ArrayDeque;
import java.util.Deque;
@ -162,9 +163,26 @@ public class FastByteArrayOutputStream extends OutputStream { @@ -162,9 +163,26 @@ public class FastByteArrayOutputStream extends OutputStream {
*/
@Override
public String toString() {
return new String(toByteArrayUnsafe());
return toString(Charset.defaultCharset());
}
/**
* Converts the buffer's contents into a string by decoding the bytes using
* the specified {@link java.nio.charset.Charset charset}.
*
* @param charset the {@linkplain java.nio.charset.Charset charset}
* to be used to decode the {@code bytes}
* @return a String decoded from the buffer's contents
*/
public String toString(Charset charset) {
if (size() == 0) {
return "";
}
if (buffers.size() == 1) {
return new String(buffers.getFirst(), 0, index, charset);
}
return new String(toByteArrayUnsafe(), charset);
}
// Custom methods

18
spring-core/src/test/java/org/springframework/util/FastByteArrayOutputStreamTests.java

@ -57,6 +57,24 @@ class FastByteArrayOutputStreamTests { @@ -57,6 +57,24 @@ class FastByteArrayOutputStreamTests {
assertThat(this.os.size()).isEqualTo(sizeBefore);
}
@Test
void stringConversion() throws Exception {
this.os.write(this.helloBytes);
assertThat(this.os.toString()).isEqualTo("Hello World");
assertThat(this.os.toString(StandardCharsets.UTF_8)).isEqualTo("Hello World");
FastByteArrayOutputStream empty = new FastByteArrayOutputStream();
assertThat(empty.toString()).isEqualTo("");
assertThat(empty.toString(StandardCharsets.US_ASCII)).isEqualTo("");
FastByteArrayOutputStream outputStream = new FastByteArrayOutputStream(5);
// Add bytes in multiple writes to ensure we get more than one buffer internally
outputStream.write(this.helloBytes, 0, 5);
outputStream.write(this.helloBytes, 5, 6);
assertThat(outputStream.toString(StandardCharsets.UTF_8)).isEqualTo("Hello World");
assertThat(outputStream.toString()).isEqualTo("Hello World");
}
@Test
void autoGrow() throws IOException {
this.os.resize(1);

2
spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java

@ -205,7 +205,7 @@ public class ContentCachingRequestWrapper extends HttpServletRequestWrapper { @@ -205,7 +205,7 @@ public class ContentCachingRequestWrapper extends HttpServletRequestWrapper {
* @see #getContentAsByteArray()
*/
public String getContentAsString() {
return new String(this.cachedContent.toByteArrayUnsafe(), Charset.forName(getCharacterEncoding()));
return this.cachedContent.toString(Charset.forName(getCharacterEncoding()));
}
/**

Loading…
Cancel
Save