在springboot集成Cloudflare R2对象存储
文章以springboot项目为例介绍了上传接口的实现
·
1. 依赖管理与版本说明
Maven 依赖配置:
<dependencies>
<!-- AWS SDK for S3 (兼容Cloudflare R2) -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>2.29.52</version>
</dependency>
<!-- EC2依赖用于区域自动识别 -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>ec2</artifactId>
<version>2.29.52</version>
</dependency>
<!-- HTTP客户端用于底层请求 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
</dependencies>
版本选择注意事项:
- 2.30.0 + 版本需额外配置签名算法

2. 配置文件与常量管理
application.yml 完整配置:
cloud:
aws:
s3:
endpoint: https://abc123.r2.cloudflarestorage.com # 替换为实际accountID
bucket-name: my-spring-boot-bucket # 替换为实际存储桶名
cdn-domain: img.example.com # 替换为自定义域名
region: auto # 自动识别区域
credentials:
access-key: YOUR_ACCESS_KEY # 替换为API访问密钥
secret-key: YOUR_SECRET_KEY # 替换为API秘密密钥
3. 核心代码实现
config代码
@Component
public class R2FileUtils implements InitializingBean {
public static String END_POINT;
public static String REGION;
public static String BUCKET_NAME;
public static String CDN_DOMAIN;
public static String ACCESS_KEY;
public static String SECRET_KEY;
@Value("${cloud.aws.s3.endpoint}")
private String endpoint;
@Value("${cloud.aws.s3.region}")
private String region;
@Value("${cloud.aws.s3.bucket-name}")
private String bucketName;
@Value("${cloud.aws.s3.cdn-domain}")
private String cdnDomain;
@Value("${cloud.aws.s3.credentials.access-key}")
private String accessKey;
@Value("${cloud.aws.s3.credentials.secret-key}")
private String secretKey;
@Override
public void afterPropertiesSet() throws Exception {
END_POINT = this.endpoint;
REGION = this.region;
BUCKET_NAME = this.bucketName;
CDN_DOMAIN = this.cdnDomain;
ACCESS_KEY = this.accessKey;
SECRET_KEY = this.secretKey;
}
}
controller代码
@RestController
@RequestMapping("/api/file")
@Api(tags = "文件上传接口")
public class FileUploadController {
@Resource
private FileUploadService fileUploadService;
@PostMapping("/r2/upload")
@ApiOperation("Cloudflare R2文件上传")
@ApiImplicitParam(name = "file", value = "上传文件", required = true,
dataType = "MultipartFile")
public CommonResult<String> uploadToR2(@RequestPart("file") MultipartFile file) {
// 前置校验
if (file.isEmpty()) {
return CommonResult.error(ErrorCode.FILE_EMPTY);
}
// 调用服务层
String url = fileUploadService.uploadToR2(file);
return CommonResult.success(url, "上传成功");
}
}
serviceImpl核心代码
@Service
public class FileUploadServiceImpl implements FileUploadService {
@Override
public String uploadToR2(MultipartFile file) {
try (InputStream inputStream = file.getInputStream()) {
// 构建S3客户端
S3Client s3Client = S3Client.builder()
.endpointOverride(URI.create(R2Config.END_POINT))
.credentialsProvider(() -> AwsBasicCredentials.create(
R2Config.ACCESS_KEY, R2Config.SECRET_KEY))
.region(Region.of(R2Config.REGION))
.build();
// 生成唯一文件名(含日期路径)
String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
String originalFilename = file.getOriginalFilename();
String fileExt = originalFilename.substring(originalFilename.lastIndexOf("."));
String objectKey = datePath + "/" + UUID.randomUUID() + fileExt;
// 构建上传请求
PutObjectRequest putRequest = PutObjectRequest.builder()
.bucket(R2Config.BUCKET_NAME)
.key(objectKey)
.contentType(file.getContentType())
.build();
// 执行上传
s3Client.putObject(putRequest,
RequestBody.fromInputStream(inputStream, file.getSize()));
// 生成可访问URL(含CDN域名)
return R2Config.CDN_DOMAIN + "/" + objectKey;
} catch (IOException | S3Exception e) {
log.error("R2文件上传失败: {}", e.getMessage(), e);
throw new FileUploadException("文件上传失败,请稍后再试");
}
}
}
接口测试

除此之外还可以限制文件大小,格式,设置定期删除等功能,示例中不再赘述。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)