Как загрузить multipart / form-data в AmazonS3, используя java sdk и web-flux? - PullRequest
1 голос
/ 28 октября 2019

У меня есть проект 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 в реактивном стиле?

1 Ответ

0 голосов
/ 02 ноября 2019

Вы не можете использовать операцию put object в этом случае. Это необходимо сделать с помощью multipart upload .

. К сожалению, новая поддержка AWS Java SDK для этой функции очень громоздка.

Вам необходимо использовать следующие операции:

Надеюсь, однажды мы получим высокоуровневый API для этого.

...