当前位置: 首页 > news >正文

spring boot集成 RustFS服务

1、安装maven依赖

<!-- AWS S3 SDK --><dependency><groupId>software.amazon.awssdk</groupId><artifactId>s3</artifactId><version>2.21.42</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency>

2、在yml配置文件中添加如下配置

rustfs:endpoint: http://IP:9000access-key: adminsecret-key: 123456bucket-name: zmtestspring:servlet:multipart:max-file-size: 10MBmax-request-size: 100MB

3、新建配置类RustFSConfig

package com.example.mcp_server_api.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;import java.net.URI;@Configuration
@ConfigurationProperties(prefix = "rustfs")
@Data
public class RustFSConfig {private String endpoint;private String accessKey;private String secretKey;private String bucketName;@Beanpublic S3Client s3Client() {return S3Client.builder().endpointOverride(URI.create(endpoint)).region(Region.US_EAST_1).credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(accessKey, secretKey))).forcePathStyle(true)  // 关键配置!RustFS 需启用 Path-Style.build();}@Beanpublic S3Presigner s3Presigner() {return S3Presigner.builder().endpointOverride(URI.create(endpoint)) // 您的RustFS地址.region(Region.US_EAST_1) // 区域,对于自建服务通常可设为任意值.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(accessKey, secretKey)))//.fipsEnabled( true).build();}
}

4、服务接口IRustFService

package com.example.mcp_server_api.service;import org.springframework.web.multipart.MultipartFile;import java.time.Duration;public interface IRustFService {//上传文件String uploadFile(MultipartFile file);//删除文件void deleteFile(String fileName);//生成预签名URLString generatePresignedUrl(String fileName, Duration expiration);
}

5、实现类

package com.example.mcp_server_api.service.impl;import com.example.mcp_server_api.service.IRustFService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.core.ResponseInputStream;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.*;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest;import java.time.Duration;
import java.util.UUID;@Service
@Slf4j
public class RustFServiceImpl implements IRustFService {@Resource@Lazyprivate S3Client s3Client;@Resource@Lazyprivate S3Presigner s3Presigner;@Value("${rustfs.bucket-name}")private String bucketName;/*** 上传文件*/@Overridepublic String uploadFile(MultipartFile file) {try {// 检查存储桶是否存在,不存在则创建if (!bucketExists(bucketName)) {createBucket(bucketName);}String fileName = generateFileName(file.getOriginalFilename());s3Client.putObject(PutObjectRequest.builder().bucket(bucketName).key(fileName).contentType(file.getContentType()).build(),RequestBody.fromInputStream(file.getInputStream(),file.getSize()));return fileName;} catch (Exception e) {log.error("文件上传失败", e);throw new RuntimeException("文件上传失败: " + e.getMessage());}}/*** 下载文件*/public byte[] downloadFile(String fileName) {try {ResponseInputStream<GetObjectResponse> response =s3Client.getObject(GetObjectRequest.builder().bucket(bucketName).key(fileName).build());return response.readAllBytes();} catch (Exception e) {log.error("文件下载失败", e);throw new RuntimeException("文件下载失败: " + e.getMessage());}}/*** 删除文件*/public void deleteFile(String fileName) {try {s3Client.deleteObject(DeleteObjectRequest.builder().bucket(bucketName).key(fileName).build());} catch (Exception e) {log.error("文件删除失败", e);throw new RuntimeException("文件删除失败: " + e.getMessage());}}@Overridepublic String generatePresignedUrl(String fileName, Duration expiration) {// 1. 构建获取对象的请求GetObjectRequest getObjectRequest = GetObjectRequest.builder().bucket(bucketName).key(fileName).build();// 2. 构建预签名请求,并设置有效期GetObjectPresignRequest presignRequest = GetObjectPresignRequest.builder().signatureDuration(expiration) // 例如: Duration.ofMinutes(10).getObjectRequest(getObjectRequest).build();// 3. 生成预签名URLPresignedGetObjectRequest presignedRequest = s3Presigner.presignGetObject(presignRequest);String url = presignedRequest.url().toString();return url;}/*** 检查存储桶是否存在*/private boolean bucketExists(String bucketName) {try {s3Client.headBucket(HeadBucketRequest.builder().bucket(bucketName).build());return true;} catch (NoSuchBucketException e) {return false;}}/*** 创建存储桶*/private void createBucket(String bucketName) {s3Client.createBucket(CreateBucketRequest.builder().bucket(bucketName).build());// 设置存储桶策略为公开可读//setBucketPolicy(bucketName);}/*** 生成唯一文件名*/private String generateFileName(String originalFileName) {String extension = "";if (originalFileName != null && originalFileName.contains(".")) {extension = originalFileName.substring(originalFileName.lastIndexOf("."));}return UUID.randomUUID() + extension;}
}

6、测试控制器

package com.example.mcp_server_api.controller;import com.example.mcp_server_api.service.IRustFService;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import java.time.Duration;
import java.util.Map;@RestController
@RequestMapping("/file")
public class FileController {@Resourceprivate IRustFService rustFService;//上传附件@PostMapping("/fileUpload")public String fileUpload(@RequestParam("file") MultipartFile file) {return rustFService.uploadFile(file);}//删除文件@DeleteMapping("/deleteFile")public String deleteFile(@RequestBody Map<String,String> paramsMap) {rustFService.deleteFile(paramsMap.get("fileName"));return "OK";}//获取临时访问的Url@PostMapping("/getFileUrl")public String getFileUrl(@RequestBody Map<String,String> map) {return rustFService.generatePresignedUrl(map.get("filePath"), Duration.ofDays(7));}}
http://www.dtcms.com/a/593699.html

相关文章:

  • 谷歌攻克AI“灾难性遗忘“难题!最新范式突破AI持续学习内存瓶颈
  • SuperMap GIS基础产品FAQ集锦(20251110)
  • Kimi K2 Thinking 量化之后再量化,模型文件缩水60%,准确率85%,部署教程来了
  • 【图像处理基石】边缘检测技术:从经典算法到实战应用
  • DevEco Studio 鸿蒙HarmonyOS 引入本地har
  • 【路径算法】IDA*与D*和Lite D* 的比较及IDA*算法详解
  • 做网站运营这工作怎么样wordpress 星 评分
  • 单一职责原则(SRP)深度解析
  • 网站建设福州公司南县网站设计
  • ESD防护设计宝典(二十八):半导体的ESD失效模式与机理
  • 关于止盈和止损的问题(一)
  • LeetCode 分类刷题:141. 环形链表
  • 在哪个网站做视频赚钱的亚马逊计划裁员1万人
  • 建材建设行业网站做网站从何开始
  • leetcode 3542
  • 【Python Maze Diary 1.1】迷宫算法术语
  • 大学计算机基础(Windows 7+Office 2010)第一章课后练习
  • PyTorch中int32和int64在性能上有什么差异
  • 机器学习入门:从零开始理解AI的核心引擎(附Python实战)
  • 【AI学习-comfyUI学习-简易加载器工作流(文生图)-各个部分学习-第七节-2】
  • 西安建设高端网站外星人建设的网站
  • Bugku-Web题目-文件包含
  • 给自己做的网站换首页北京大良网站建设
  • 网站的内容规划怎么写nodejs做网站还是app
  • 从“识图”到“购得”:图片搜索商品如何重构消费与供应链逻辑?
  • 通过OCR实现验证码识别
  • 33.Transformer架构
  • 环形链表快慢指针全解析:相遇必然性与多步速追击证明
  • 长沙微网站开发中小型企业网站优化推广
  • 构建一个基于Flask的URL书签管理工具