Browse Source

Add setBody with byte[] to StreamingHttpOutputMessage

Sometimes the content to write is already buffered, but requires boilerplate
to write through a Body callback.

See gh-33785
pull/34223/head
rstoyanchev 1 year ago
parent
commit
4b9be5aaf8
  1. 25
      spring-web/src/main/java/org/springframework/http/StreamingHttpOutputMessage.java
  2. 24
      spring-web/src/main/java/org/springframework/http/client/AbstractBufferingClientHttpRequest.java
  3. 14
      spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java

25
spring-web/src/main/java/org/springframework/http/StreamingHttpOutputMessage.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,6 +19,8 @@ package org.springframework.http; @@ -19,6 +19,8 @@ package org.springframework.http;
import java.io.IOException;
import java.io.OutputStream;
import org.springframework.util.StreamUtils;
/**
* Represents an HTTP output message that allows for setting a streaming body.
* Note that such messages typically do not support {@link #getBody()} access.
@ -35,6 +37,27 @@ public interface StreamingHttpOutputMessage extends HttpOutputMessage { @@ -35,6 +37,27 @@ public interface StreamingHttpOutputMessage extends HttpOutputMessage {
*/
void setBody(Body body);
/**
* Variant of {@link #setBody(Body)} for a non-streaming write.
* @param body the content to write
* @throws IOException if an I/O exception occurs
* @since 7.0
*/
default void setBody(byte[] body) throws IOException {
setBody(new Body() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
StreamUtils.copy(body, outputStream);
}
@Override
public boolean repeatable() {
return true;
}
});
}
/**
* Defines the contract for bodies that can be written directly to an

24
spring-web/src/main/java/org/springframework/http/client/AbstractBufferingClientHttpRequest.java

@ -64,35 +64,25 @@ abstract class AbstractBufferingClientHttpRequest extends AbstractClientHttpRequ @@ -64,35 +64,25 @@ abstract class AbstractBufferingClientHttpRequest extends AbstractClientHttpRequ
/**
* Execute with the given request and body.
* @param request the request to execute with
* @param body the body to send
* @param bufferedOutput the body to write
* @param bufferResponse whether to buffer the response
* @return the resulting response
* @throws IOException in case of I/O errors from execution
* @since 7.0
*/
protected ClientHttpResponse executeWithRequest(
ClientHttpRequest request, byte[] body, boolean bufferResponse) throws IOException {
ClientHttpRequest request, byte[] bufferedOutput, boolean bufferResponse) throws IOException {
if (body.length > 0) {
if (bufferedOutput.length > 0) {
long contentLength = request.getHeaders().getContentLength();
if (contentLength > -1 && contentLength != body.length) {
request.getHeaders().setContentLength(body.length);
if (contentLength > -1 && contentLength != bufferedOutput.length) {
request.getHeaders().setContentLength(bufferedOutput.length);
}
if (request instanceof StreamingHttpOutputMessage streamingOutputMessage) {
streamingOutputMessage.setBody(new StreamingHttpOutputMessage.Body() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
StreamUtils.copy(body, outputStream);
}
@Override
public boolean repeatable() {
return true;
}
});
streamingOutputMessage.setBody(bufferedOutput);
}
else {
StreamUtils.copy(body, request.getBody());
StreamUtils.copy(bufferedOutput, request.getBody());
}
}

14
spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -404,17 +404,7 @@ public class FormHttpMessageConverter implements HttpMessageConverter<MultiValue @@ -404,17 +404,7 @@ public class FormHttpMessageConverter implements HttpMessageConverter<MultiValue
outputMessage.getHeaders().setContentLength(bytes.length);
if (outputMessage instanceof StreamingHttpOutputMessage streamingOutputMessage) {
streamingOutputMessage.setBody(new StreamingHttpOutputMessage.Body() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
StreamUtils.copy(bytes, outputStream);
}
@Override
public boolean repeatable() {
return true;
}
});
streamingOutputMessage.setBody(bytes);
}
else {
StreamUtils.copy(bytes, outputMessage.getBody());

Loading…
Cancel
Save