Use readNBytes in StringHttpMessageConverter when contentLength is available

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

Closes gh-30942
This commit is contained in:
Patrick Strawderman 2023-07-25 08:28:53 -07:00 committed by Sam Brannen
parent d890827bae
commit 7636eecb48
2 changed files with 19 additions and 1 deletions

View File

@ -93,7 +93,14 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
@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

View File

@ -70,6 +70,17 @@ public class StringHttpMessageConverterTests {
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\"}";