springboot实现文件上传到华为云的obs

news/2025/2/26 6:17:52

一、前言
有时在项目中需要使用一些存储系统来存储文件,那么当项目要接入obs作为存储系统时,就会利用obs来进行文件的上传下载,具体实现如下。

二、如何通过obs实现文件的上传下载?
1.添加相关的obs的maven依赖。

 <dependency>
            <groupId>com.huaweicloud</groupId>
            <artifactId>esdk-obs-java-bundle</artifactId>
            <version>3.23.9</version>
        </dependency>

2.配置obs客户端连接。

@Configuration  
@Data
public class OBSConfig {  

    @Value("${obs.accessKey}")  
    private String accessKey;  

    @Value("${obs.secretKey}")  
    private String secretKey;  

    @Value("${obs.endpoint}")  
    private String endpoint;  
    
    @Value("${obs.bucket}")
    private String bucketName;
    
}  

3.在YAML添加obs配置。

obs:
  endpoint: http://xxxxxx:xxxx
  accessKey: xxxxxxxx
  secretKey: xxxxxxxxxxx
  bucket: my-bucket

4.定义obs工具类,代码如下:

import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.CompleteMultipartUploadRequest;
import com.obs.services.model.CompleteMultipartUploadResult;
import com.obs.services.model.ObjectMetadata;
import com.obs.services.model.PutObjectRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.InputStream;
import java.util.UUID;

@Component
public class ObsUtil {
  @Resource
   private OBSConfig  oBSConfig;
  private ObsClient obsClient;

    public ObsClient getClient() {
        if (obsClient == null) {
            obsClient = new ObsClient(oBSConfig.getAccessKey, oBSConfig.getSecretKey, oBSConfig.getEndPoint);
        }
        return obsClient;
    }
    /**
     * 上传文件到OBS
     *
     * @param file 待上传的文件
     * @return 返回文件的访问路径
     */
    public String uploadFile(File file) {
        try (ObsClient obsClient = getObsClient()) {
            // 生成唯一的文件名
            String fileName = UUID.randomUUID().toString() + "-" + file.getName();
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileName, file);

            // 设置元数据(可选)
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType("application/octet-stream");
            putObjectRequest.setMetadata(metadata);

            obsClient.putObject(putObjectRequest);
            return endpoint + "/" + bucketName + "/" + fileName;
        } catch (ObsException e) {
            throw new RuntimeException("上传文件失败:" + e.getMessage(), e);
        }
    }

    /**
     * 上传文件流到OBS
     *
     * @param inputStream 文件输入流
     * @param fileName    文件名
     * @return 返回文件的访问路径
     */
    public String uploadInputStream(InputStream inputStream, String fileName) {
        try (ObsClient obsClient = getObsClient()) {
            // 生成唯一的文件名
            String objectKey = UUID.randomUUID().toString() + "-" + fileName;
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectKey, inputStream);

            // 设置元数据(可选)
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType("application/octet-stream");
            putObjectRequest.setMetadata(metadata);

            obsClient.putObject(putObjectRequest);
            return endpoint + "/" + bucketName + "/" + objectKey;
        } catch (ObsException e) {
            throw new RuntimeException("上传文件流失败:" + e.getMessage(), e);
        }
    }

    /**
     * 下载文件
     *
     * @param objectKey 对象键(文件名)
     * @param savePath  保存路径
     */
    public Inputstream downloadFile(String objectKey, String savePath) {
        try (ObsClient obsClient = getObsClient()) {
        GetObjectRequest request = new GetObjectRequest();
        request.setBucketName(StringUtils.isEmpty(bucket) ? oBSConfig.getBucket : bucket);
        String objectName = (originFilePath == null ? "" : originFilePath) + fileName;
        objectName = objectName.charAt(0) == '/' ? objectName.substring(1) : objectName;
        request.setObjectKey(objectName);
        if (offset != null) {
            request.setRangeStart(offset);
            if (length != null) {
                request.setRangeEnd(offset + length);
            }
        }
        ObsObject object = client.getObject(request);
        return object.getObjectContent();
        } catch (ObsException e) {
            throw new RuntimeException("下载文件失败:" + e.getMessage(), e);
        }
    }

    /**
     * 删除文件
     *
     * @param objectKey 对象键(文件名)
     */
    public void deleteFile(String objectKey) {
        try (ObsClient obsClient = getObsClient()) {
            obsClient.deleteObject(bucketName, objectKey);
        } catch (ObsException e) {
            throw new RuntimeException("删除文件失败:" + e.getMessage(), e);
        }
    }
}

5.文件上传接口实现示例:

@RestController  
@RequestMapping("/obs")  
public class OBSUploadController {  

    @Autowired  
    private ObsUtil obsUtil ;  

    @PostMapping("/upload")  
    public ResponseEntity<String> uploadFile(  
        @RequestParam("file") MultipartFile file
    ) {  
        try {  
            obsUtil.uploadFile(file.getInputStream(),"xxxx");  
            return ResponseEntity.ok("OBS路径: " + objectKey);  
        } catch (ObsException e) {  
            return ResponseEntity.status(e.getResponseCode())  
                .body("OBS服务异常: " + e.getErrorMessage());  
        } catch (Exception e) {  
            return ResponseEntity.internalServerError()  
                .body("上传失败: " + e.getMessage());  
        }  
    }  
}  

有兴趣的可以试一试。


http://www.niftyadmin.cn/n/5868174.html

相关文章

JavaScript函数-函数的两种声明方式

在JavaScript中&#xff0c;函数是构建复杂逻辑和实现代码重用的基本单元。了解如何正确地定义和使用函数对于任何JavaScript开发者来说都是至关重要的。本文将详细介绍JavaScript函数的两种主要声明方式&#xff1a;函数声明&#xff08;Function Declaration&#xff09;和函…

MySQL中的UNION操作符

前言 在MySQL数据库的世界里&#xff0c;数据查询是一项核心操作。而UNION操作符作为数据查询中的一个强大工具&#xff0c;能够帮助开发者高效地处理多个结果集的合并。 1. 什么是UNION操作符 在MySQL中&#xff0c;UNION并不是一个函数&#xff0c;而是一个用于合并两个或…

LangChain大模型应用开发:LangGraph快速构建Agent工作流应用

介绍 大家好&#xff0c;博主又来给大家分享知识了。今天给大家分享的内容是使用LangChain进行大规模应用开发中的LangGraph快速构建Agent工作流应用。 通过对前几次对LangChain的技术分享。我们知道LangChain作为一个强大的工具集&#xff0c;为开发者们提供了丰富的资源和便…

FPGA 常用的片上缓存方式

FPGA 常用的片上缓存方式 FIFO 1. FIFO的基本概念 FIFO&#xff08;First In First Out&#xff0c;先进先出队列&#xff09;是一种关键的数据缓冲结构&#xff0c;主要用于解决数据速率匹配、跨时钟域同步和流量控制等问题。FIFO 按写入顺序存储数据&#xff0c;并按相同顺…

【深度学习神经网络学习笔记(二)】神经网络基础

神经网络基础 神经网络基础前言1、Logistic 回归2、逻辑回归损失函数3、梯度下降算法4、导数5、导数计算图6、链式法则7、逻辑回归的梯度下降 神经网络基础 前言 Logistic 回归是一种广泛应用于统计学和机器学习领域的广义线性回归模型&#xff0c;主要用于解决二分类问题。尽…

AcWing 蓝桥杯集训·每日一题2025

题目链接 : 5437. 拐杖糖盛宴 题意: 有m个不同的糖果和n个不同高度的奶龙, 奶龙可以根据自己的身高去吃糖果,糖果垂直于地面,对于一个糖果都需要让每个奶龙尝试能否吃到,如果吃到则减去相应吃到的长度, 奶龙长高吃掉糖果的长度即可,根据长度进行判断, 分类讨论。 解题思路 : …

Java包装类性能优化:深入解析Integer享元模式的源码实现

前言 在Java中&#xff0c;每一个基本类型都有对应的包装类。其中&#xff0c;Integer作为最常用的包装类之一&#xff0c;其内部实现巧妙地运用了享元模式&#xff08;Flyweight Pattern&#xff09;&#xff0c;通过对象缓存机制显著提升了性能。本文将深入剖析Integer类的享…

Java进阶学习笔记64——IO流

IO流&#xff1a; 输入输出流&#xff0c;就是读写数据的。 IO流的应用场景&#xff1a; 怎么去学习IO流&#xff1f; 1、先搞清楚IO流的分类、体系&#xff1f; 2、再挨个学习每个IO流的作用、用法。 IO流的分类&#xff1a; 按流的方向分为&#xff1a; 按流中数据的最小…