提问人:TheStranger 提问时间:9/25/2023 最后编辑:TheStranger 更新时间:9/25/2023 访问量:27
为什么我总是收到“无法重试请求,因为无法重置请求流”?
Why do I keep getting 'Request cannot be retried, because the request stream could not be reset.'?
问:
我有这个问题,在过去的两周里我一直被困住了。我有这个代码,它基本上接受一个包含文件的 HttpServletRequest,并将其上传到 S3:
private UploadResultData uploadPackageAndCalculateMD5(HttpServletRequest request, String bucket, String uploadUrl) {
try {
// Create an InputStream from the request
InputStream fileInputStream = request.getInputStream();
// Create a DigestInputStream to calculate MD5 hash
MessageDigest md = MessageDigest.getInstance("MD5");
DigestInputStream digestInputStream = new DigestInputStream(inputStream, md);
// Create a CountingInputStream to calculate file size
CountingInputStream countingStream = new CountingInputStream(digestInputStream);
// Create an UploadRequest to upload the file to S3
UploadRequest uploadRequest = UploadRequest.builder()
.putObjectRequest(b -> b.bucket(bucket).key(uploadUrl))
.requestBody(AsyncRequestBody.fromInputStream(countingStream, request.getContentLengthLong(), s3Pool))
.addTransferListener(new TransferListener() {
double lastKnownProgress = 0;
@Override
public void bytesTransferred(Context.BytesTransferred context) {
TransferProgressSnapshot snapshot = context.progressSnapshot();
OptionalDouble optionalDouble = snapshot.ratioTransferred();
if (optionalDouble.isPresent()) {
double currentProgress = optionalDouble.getAsDouble();
if (Math.abs(currentProgress - lastKnownProgress) >= 0.01) { // Update every 1%
lastKnownProgress = currentProgress;
// Create a Map to store progress data
Map<String, Object> progressData = new HashMap<>();
progressData.put("transfer", humanReadableByteCountSI(snapshot.transferredBytes()));
progressData.put("total", humanReadableByteCountSI(snapshot.totalBytes().getAsLong()));
progressData.put("ratio", optionalDouble.getAsDouble());
UploadController.this.updateProgress(uploadUrl, progressData); // use key to update specific progress
}
}
}
})
.build();
// Upload the file to S3
Upload upload = s3TransferManager.upload(uploadRequest);
// Wait for the upload to complete
PutObjectResponse response = upload.completionFuture().join().response();
// Calculate MD5 hash and file size
byte[] digest = md.digest();
String md5Hash = DatatypeConverter.printHexBinary(digest).toLowerCase();
System.out.println("MD5 hash: " + md5Hash);
long fileSize = countingStream.getByteCount();
System.out.println("File size: " + fileSize);
// Check if the md5 hash was calculated
if (md5Hash.isEmpty()) {
log.error("MD5 hash calculation failed");
return null;
}
// Check if the file size was calculated
if (fileSize == 0) {
log.error("File size calculation failed");
return null;
}
System.out.println("File Upload Done!");
// Create an UploadResultData object to return
UploadResultData uploadResultData = new UploadResultData();
uploadResultData.setMd5Hash(md5Hash);
uploadResultData.setFileSize(fileSize);
return uploadResultData;
} catch (Exception e) {
// Log the error and return null to indicate failure
log.error("Failed to upload package: " + e.getMessage());
e.printStackTrace();
return null;
}
}
当我上传超过 5 GB 的文件时,或者如果客户端取消上传请求,我会收到以下错误:
Request cannot be retried, because the request stream could not be reset.
这是我的班级:AwsConfig
@Configuration
public class AwsConfig {
private static final Region awsRegion = Region.US_EAST_1;
@Value("************")
private String accessKey;
@Value("************")
private String secretKey;
@Value("************")
private String endpoint;
@Bean
public S3Client s3Client() {
if (endpoint == null || endpoint.isEmpty()) throw new RuntimeException("needs s3 endpoint");
var s3Url = endpoint.replaceAll("/$", ""); // remove trailing slash
AwsBasicCredentials credentials = AwsBasicCredentials.create(accessKey, secretKey);
return S3Client.builder()
.credentialsProvider(StaticCredentialsProvider.create(credentials))
.endpointOverride(URI.create(s3Url))
.region(awsRegion)
.build();
}
@Bean
public S3AsyncClient s3AsyncClient() {
AwsBasicCredentials credentials = AwsBasicCredentials.create(accessKey, secretKey);
return S3AsyncClient.builder()
.credentialsProvider(StaticCredentialsProvider.create(credentials))
.endpointOverride(URI.create(endpoint))
.region(awsRegion)
.build();
}
@Bean
public S3TransferManager asyncTransferManager(S3AsyncClient s3AsyncClient) {
return S3TransferManager.builder()
.s3Client(s3AsyncClient)
.build();
}
}
是什么导致了错误,我该如何修复它?
答: 暂无答案
评论