Lambda生成PDF后用ByteOutputStream上传S3报错,求解决及替代方案
问题分析与解决方案
问题根源
你代码中生成的PDF出现加载失败的核心原因是错误地将二进制PDF数据通过UTF-8字符串中转。PDF是二进制格式文件,并非文本,UTF-8编码无法完整保留所有二进制字节信息,转字符串再转回字节的过程会破坏原始数据,导致上传到S3的文件损坏。
修正后的代码
直接跳过字符串转换步骤,使用ByteArrayOutputStream的原始二进制数据上传:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); pdDocument.save(byteArrayOutputStream); // 直接获取PDF的原始二进制字节数组 byte[] pdfBytes = byteArrayOutputStream.toByteArray(); final InputStream input = new ByteArrayInputStream(pdfBytes); ObjectMetadata objectMetadata = new ObjectMetadata(); objectMetadata.setContentType("application/pdf"); // 设置正确的PDF内容类型 objectMetadata.setContentLength(pdfBytes.length); // 使用实际字节长度 s3Client.putObject(new PutObjectRequest(bucketName, fileName, input, objectMetadata));
无需本地存储的其他上传方法
1. 使用TransferManager(AWS SDK v1)
适合处理大文件自动分块上传,代码更简洁:
TransferManager transferManager = TransferManagerBuilder.standard().withS3Client(s3Client).build(); ObjectMetadata objectMetadata = new ObjectMetadata(); objectMetadata.setContentType("application/pdf"); Upload upload = transferManager.upload( bucketName, fileName, new ByteArrayInputStream(pdfBytes), objectMetadata ); upload.waitForCompletion(); // 等待上传完成
2. 使用AWS SDK v2的直接字节上传
如果已经升级到SDK v2,可直接用RequestBody.fromBytes上传:
PutObjectRequest putObjectRequest = PutObjectRequest.builder() .bucket(bucketName) .key(fileName) .contentType("application/pdf") .build(); s3Client.putObject(putObjectRequest, RequestBody.fromBytes(pdfBytes));
内容的提问来源于stack exchange,提问作者Riya Bhardwaj
相关产品推荐
相关产品推荐

