Код: Выделить всё
package com.util.s3;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
import software.amazon.awssdk.core.async.AsyncRequestBody;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
@Component
public class S3AsyncUploadService {
private final S3AsyncClient s3AsyncClient;
public S3AsyncUploadService(S3AsyncClient s3AsyncClient) {
this.s3AsyncClient = s3AsyncClient;
}
public Mono uploadFile(String bucketName, String fileName, byte[] fileContent) {
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(fileName)
.build();
return Mono.fromFuture(
s3AsyncClient.putObject(
putObjectRequest,
AsyncRequestBody.fromBytes(fileContent)
)
).then();
}
}
< /code>
s3uploadservice.java
package com.util.s3;
import org.springframework.stereotype.Component;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
@Component
public class S3UploadService {
private final S3Client s3Client;
public S3UploadService(S3Client s3Client) {
this.s3Client = s3Client;
}
public void uploadFile(String bucketName, String fileName, byte[] fileContent) {
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(fileName)
.build();
s3Client.putObject(putObjectRequest, RequestBody.fromBytes(fileContent));
}
}
< /code>
s3resource.java
package com.util.resource;
import com.util.s3.S3AsyncUploadService;
import com.util.s3.S3UploadService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.CreateBucketRequest;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Response;
import software.amazon.awssdk.services.s3.model.S3Object;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/s3")
public class S3Resource {
private final S3UploadService s3UploadService;
private final S3AsyncUploadService s3AsyncUploadService;
private final S3Client s3Client;
@Value("${aws.s3.bucket}")
private String bucketName;
public S3Resource(S3UploadService s3UploadService, S3AsyncUploadService s3AsyncUploadService, S3Client s3Client) {
this.s3UploadService = s3UploadService;
this.s3AsyncUploadService = s3AsyncUploadService;
this.s3Client = s3Client;
}
@GetMapping("/upload-string")
public Mono uploadString(@RequestParam("content") String content) {
s3Client.createBucket(CreateBucketRequest.builder().bucket(bucketName).build());
String syncKey = "sync-uploaded.txt";
String asyncKey = "async-uploaded.txt";
byte[] bytes = content.getBytes(StandardCharsets.UTF_8);
// 1. Synchronous upload
s3UploadService.uploadFile(bucketName, syncKey, bytes);
// 2. Asynchronous upload
return s3AsyncUploadService.uploadFile(bucketName, asyncKey, bytes)
.then(Mono.fromCallable(() -> {
ListObjectsV2Request listReq = ListObjectsV2Request.builder()
.bucket(bucketName)
.build();
ListObjectsV2Response listRes = s3Client.listObjectsV2(listReq);
Map keysWithSize = listRes.contents().stream()
.collect(Collectors.toMap(S3Object::key, S3Object::size));
return ResponseEntity.ok(keysWithSize);
}));
}
}
Я использую Java 21 с Spring Boot Webflux и AWS SDK V2. У меня есть две службы для загрузки файлов в S3: < /p>
[*] s3uploadService использует синхронные s3client - работает, как и ожидалось. пусто. Asynchronous, использует asyncrequestbody.frombytes (...). < /p>
< /li>
endpoint /s3 /upload-string загружает простую строку для обоих сервисов: < /p>
- Создает Secute-Service, используя Scuest, One Service. Async Service. < /li>
перечисляет объекты и возвращает размеры объектов. < /li>
Синхрозагруженный файл имеет ожидаемый размер. Async-Uploaded File имеет размер 0.
наблюдаемое поведение:
- li. /> Async-uploaded.txt присутствует в ковше, но имеет 0 байтов. < /p>
< /li>
< /ul>
ожидается: < /strong> < /p>
оба увеличения должны хранить тот же содержащий (то же самое (то же самое используется. />
Что я попробовал:
Подтверждено, что массив входных байтов не пуст. /> < /li>
Проверьте, что клавиши ведения и объекта правильны. < /p>
< /li>
< /ul>
Вопрос: < /strong>
Что может вызвать S3AsyncClient для загрузки файла 0-byte, даже если содержание присутствует?>
Подробнее здесь: https://stackoverflow.com/questions/797 ... ty-content