I have a java spring-boot project with spring-boot-starter-webflux. I have a rest controller:
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.core.async.AsyncRequestBody;
...
@PostMapping(path = "/path", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = APPLICATION_JSON_VALUE)
public Mono<String> submitMultipartInstance(@RequestPart Flux<FilePart> partFlux) {
String bucketName = ...
String key = ...
PutObjectRequest request = PutObjectRequest.builder()
.bucket(bucketName)
.key(key)
.build();
CompletableFuture<PutObjectResponse> completableFuture = s3AsyncClient.putObject(request, createAsyncBody(partFlux));
return Mono.defer(() -> Mono.fromFuture(completableFuture))
.map(PutObjectResponse::toString)
}
private AsyncRequestBody createAsyncBody(Flux<FilePart> part) {
return new AsyncRequestBody() {
@Override
public Optional<Long> contentLength() {
return Optional.empty(); // what value to return from here?
}
@Override
public void subscribe(Subscriber<? super ByteBuffer> s) {
part.flatMap(FilePart::content).map(toByteBuffer()).subscribe(s);
}
private Function<DataBuffer, ByteBuffer> toByteBuffer() {
return (buffer) -> {
byte[] bytes = new byte[buffer.asByteBuffer().remaining()];
try {
return ByteBuffer.wrap(bytes);
} finally {
DataBufferUtils.release(buffer.read(bytes));
}
};
}
};
}
and I receive message (expectedly)
Caused by: software.amazon.awssdk.services.s3.model.S3Exception: You must provide the Content-Length HTTP header. (Service: S3, Status Code: 411, Request ID: ...)
How to upload multipart to s3 in reactive style?