Spring Boot上传图片到S3 Bucket报错:未指定流数据的内容长度
问题根因
你代码中提取的Content-length、Content-type被作为用户自定义元数据存入ObjectMetadata,AWS S3 SDK不会将自定义元数据识别为请求需要的标准头部参数,因此上传流时无法获取内容长度,触发内存缓冲警告,文件体积较大时就会出现报错。初期运行正常是因为当时上传的图片体积较小,SDK默认内存缓冲可以承载,后续上传文件体积超过缓冲阈值后就会稳定触发问题。
修复方案
修改FileStore.java的save方法,单独设置S3标准元数据
S3的ObjectMetadata提供了专用的内容长度、内容类型设置接口,需要单独调用这两个接口将参数写入标准头部,修改后代码如下:
public void save(String path, String fileName, Optional<Map<String, String>> optionalMetadata, InputStream inputStream) { ObjectMetadata metadata = new ObjectMetadata(); optionalMetadata.ifPresent(map -> { if (!map.isEmpty()) { // 写入S3要求的标准元数据字段 if (map.containsKey("Content-length")) { metadata.setContentLength(Long.parseLong(map.get("Content-length"))); } if (map.containsKey("Content-type")) { metadata.setContentType(map.get("Content-type")); } // 其余字段作为自定义元数据存储 map.forEach(metadata::addUserMetadata); } }); try { s3.putObject(path, fileName, inputStream, metadata); } catch (AmazonServiceException | NumberFormatException e) { throw new IllegalStateException("Failed to store file to s3", e); } }
可选优化(大文件场景)
如果需要上传大于100MB的文件,建议使用AWS SDK提供的TransferManager进行分片上传,进一步降低内存溢出风险。
内容的提问来源于stack exchange,提问作者Nuno Aparício
相关产品推荐
相关产品推荐

