You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot上传含特殊字符文件至S3,MinioClient获取预签名URL报错

解决MinioClient获取带特殊字符文件名的S3预签名URL时"No such key"错误

问题根源

S3/MinIO的对象键(Object Key)对特殊字符(如中文、空格、!@#等)的识别依赖统一的URL编码规则,如果上传时的对象键编码和生成预签名URL时使用的键编码不一致,就会出现键不匹配,触发"No such key"错误。

解决方案

1. 上传阶段统一编码对象键

上传文件时,对原始文件名进行符合S3规范的URL编码,再作为对象键上传:

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

// 从上传文件中获取原始文件名,例如"我的文件!@#.txt"
String originalFileName = multipartFile.getOriginalFilename();
// 执行URL编码,将URLEncoder默认生成的"+"替换为S3要求的"%20"
String encodedObjectKey = URLEncoder.encode(originalFileName, StandardCharsets.UTF_8)
        .replace("+", "%20");

// 执行上传操作
minioClient.putObject(
        PutObjectArgs.builder()
                .bucket("your-bucket-name")
                .object(encodedObjectKey) // 使用编码后的键
                .stream(multipartFile.getInputStream(), multipartFile.getSize(), -1)
                .contentType(multipartFile.getContentType())
                .build()
);

注意:如果对象键包含路径(如docs/我的文件.txt),不要编码路径分隔符/,可拆分路径和文件名分别处理后再拼接。

2. 生成预签名URL时使用相同编码的对象键

生成预签名URL必须和上传时的编码键完全一致,不能使用原始文件名:

// 必须使用上传阶段生成的encodedObjectKey
String presignedUrl = minioClient.getPresignedObjectUrl(
        GetPresignedObjectUrlArgs.builder()
                .method(Method.GET)
                .bucket("your-bucket-name")
                .object(encodedObjectKey)
                .expiry(7, TimeUnit.DAYS) // 设置URL有效期
                .build()
);

3. 处理已上传的未编码对象

如果已经上传了未编码的带特殊字符对象,查询时需要对原始文件名做相同编码后再生成URL:

String originalOldFileName = "已上传的特殊文件名!@#.pdf";
// 执行和上传阶段一致的编码
String encodedOldKey = URLEncoder.encode(originalOldFileName, StandardCharsets.UTF_8)
        .replace("+", "%20");

// 用编码后的键生成预签名URL
String presignedUrl = minioClient.getPresignedObjectUrl(
        GetPresignedObjectUrlArgs.builder()
                .method(Method.GET)
                .bucket("your-bucket-name")
                .object(encodedOldKey)
                .expiry(7, TimeUnit.DAYS)
                .build()
);

4. 关键注意事项

  • 编码一致性:上传和查询必须严格使用同一套编码规则,这是解决问题的核心。
  • 禁止手动拼接URL:不要自行拼接预签名URL,MinioClient的API会自动处理签名中的编码细节,手动拼接极易导致签名或键不匹配。
  • 覆盖特殊字符范围:所有非ASCII字符、空格、以及!@#$%^&*()等符号都需要按规则编码,避免遗漏。

内容的提问来源于stack exchange,提问作者tej

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 14:40:04