У меня есть проект java spring-boot с spring-boot-starter-webflux. У меня есть контроллер отдыха:
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));
}
};
}
};
}
, и я получаю сообщение (как ожидается)
Причина: software.amazon.awssdk.services.s3.model.S3Exception: Вы должныпредоставить HTTP-заголовок Content-Length. (Услуга: S3, код статуса: 411, идентификатор запроса: ...)
Как загрузить составную часть на s3 в реактивном стиле?