Skip to content

Commit

Permalink
Use readNBytes in StringHttpMessageConverter when contentLength is av…
Browse files Browse the repository at this point in the history
…ailable

When the content length is known, use readNBytes on the InputStream in
StringHttpMessageConverter, which avoids some extra copying and allocations.

Closes gh-30942
  • Loading branch information
kilink authored and sbrannen committed Aug 4, 2023
1 parent d890827 commit 7636eec
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 1 deletion.
Expand Up @@ -93,7 +93,14 @@ public boolean supports(Class<?> clazz) {
@Override
protected String readInternal(Class<? extends String> clazz, HttpInputMessage inputMessage) throws IOException {
Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType());
return StreamUtils.copyToString(inputMessage.getBody(), charset);
long length = inputMessage.getHeaders().getContentLength();
final byte[] bytes;
if (length >= 0 && length <= Integer.MAX_VALUE) {
bytes = inputMessage.getBody().readNBytes((int) length);
} else {
bytes = inputMessage.getBody().readAllBytes();
}
return new String(bytes, charset);
}

@Override
Expand Down
Expand Up @@ -70,6 +70,17 @@ public void read() throws IOException {
assertThat(result).as("Invalid result").isEqualTo(body);
}

@Test
public void readWithContentLengthHeader() throws IOException {
String body = "Hello World";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes(StandardCharsets.UTF_8));
inputMessage.getHeaders().setContentLength(body.length());
inputMessage.getHeaders().setContentType(TEXT_PLAIN_UTF_8);
String result = this.converter.read(String.class, inputMessage);

assertThat(result).as("Invalid result").isEqualTo(body);
}

@Test // gh-24123
public void readJson() throws IOException {
String body = "{\"result\":\"\u0414\u0410\"}";
Expand Down

0 comments on commit 7636eec

Please sign in to comment.