SpringBoot整合华为云OBS实现文件上传下载

首先我们要添加对应的依赖

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

不要忘记在启动类上添加

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

然后在对应的配置文件添加华为云对应的密钥,没有的话可以去华为云获取对应密钥

#obs
huawei:
  obs:
    ak: xxxxxxxxxxxx
    sk: xxxxxxxxxxxxxx
    upload:
      endPoint: obs.xxxxxx.xxxxxx.com
    bucketName: xxxxx
    parentDir:  xxx

然后我们创建对应的config类

package Hwei.OBS.demo.config;

import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

/**
 * 华为obs配置类
 */
@Data
@Slf4j
@Configuration
public class HweiOBSConfig {

    @Value("${huawei.obs.ak:home}")
    private String accessKey;
    @Value("${huawei.obs.sk:home}")
    private String securityKey;
    @Value("${huawei.obs.upload.endPoint:home}")
    private String endPoint;
    @Value("${huawei.obs.bucketName:home}")
    private String bucketName;

    /**
     * 创建实例
     * @return
     */
    public ObsClient getInstance(){
        return new ObsClient(accessKey,securityKey,endPoint);
    }

    /**
     * 销毁实列
     * @param obsClient
     */
    public void destroy(ObsClient obsClient)  {
        try{
            obsClient.close();
        }catch (ObsException e){
            log.error("obs执行失败",e);
        }catch (Exception e){
            log.error("执行失败",e);
        }
    }


}

这里我把需要的上传下载的方法封装起来了,这里获取到了文件上传的进度,如果前后台分离可以使用webSocket进行实时通讯,在这里就不详细讲了。

package Hwei.OBS.demo.util;

import Hwei.OBS.demo.config.HweiOBSConfig;
import Hwei.OBS.demo.dto.FileUploadStatus;
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.*;

import jdk.internal.util.xml.impl.Input;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

@Slf4j
@Configuration
public class HweiOBSUtil {
    @Autowired
    private HweiOBSConfig hweiOBSConfig;


    /**
     * 文件上传
     * @param uploadFile 上传的文件
     * @param FileName 文件名称
     * @return 返回的路径
     */
    public PutObjectResult fileUpload(MultipartFile uploadFile, String FileName){
        ObsClient obsClient=null;
        try {
            //创建实例
            obsClient = hweiOBSConfig.getInstance();
            //获取文件信息
            InputStream inputStream = uploadFile.getInputStream();
            UploadFileRequest request1 = new UploadFileRequest(hweiOBSConfig.getBucketName(), FileName);
            long available = inputStream.available();
            PutObjectRequest request = new PutObjectRequest(hweiOBSConfig.getBucketName(), java.lang.String.valueOf(FileName), inputStream);
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentLength(available);
            request.setMetadata(objectMetadata);
            //设置公共读
            request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
            PutObjectResult putObjectResult = obsClient.putObject(request);
            return putObjectResult;
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //销毁实例
            hweiOBSConfig.destroy(obsClient);
        }
        return null;
    }
    /**
     * 获取文件上传进度
     * @param fileName
     * @return
     */
    public FileUploadStatus getFileUploadPlan(String objectName){
        ObsClient obsClient=null;
        FileUploadStatus fileUploadStatus = new FileUploadStatus();
        try {
            obsClient=hweiOBSConfig.getInstance();
            GetObjectRequest request = new GetObjectRequest(hweiOBSConfig.getBucketName(), objectName);
            request.setProgressListener(new ProgressListener() {
                @Override
                public void progressChanged(ProgressStatus status) {
                    //上传的平均速度
                    fileUploadStatus.setAvgSpeed(status.getAverageSpeed());
                    //上传的百分比
                    fileUploadStatus.setPct(String.valueOf(status.getTransferPercentage()));
                }
            });
            // 每下载1MB数据反馈下载进度
            request.setProgressInterval(1024*1024L);
            ObsObject obsObject = obsClient.getObject(request);
            // 读取对象内容
            InputStream input= obsObject.getObjectContent();
            byte[] b = new byte[1024];
            ByteArrayOutputStream byteArrayOutputStream= new ByteArrayOutputStream();
            int len;
            while ((len=input.read(b))!=-1 ){
                //将每一次的数据写入缓冲区
                byteArrayOutputStream.write(b,0,len);
            }
            byteArrayOutputStream.close();
            input.close();
            return fileUploadStatus;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            hweiOBSConfig.destroy(obsClient);
        }
        return null;
    }

    /**
     * 文件下载
     * @param request
     * @param response
     * @param fileName 文件名称
     * @return
     */
    public int fileDownload(HttpServletRequest request, HttpServletResponse response, String fileName){
        try {
            ObsClient obsClient = hweiOBSConfig.getInstance();
            ObsObject obsObject = obsClient.getObject(hweiOBSConfig.getBucketName(), fileName);
            InputStream input = obsObject.getObjectContent();
            //缓冲文件输出流
            BufferedOutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            //设置让浏览器弹出下载提示框,而不是直接在浏览器中打开
            response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
            IOUtils.copy(input,outputStream);
            outputStream.flush();
            outputStream.close();
            input.close();
            return 0;
        }catch (Exception e){
            log.error("文件下载失败:{}",e.getMessage());
            return 1;
        }

    }
}

对应的Controller,这里在上传的时候去校验redis是否有上传成功的,如果有就直接返回对应的值,实现了秒传的效果。

package Hwei.OBS.demo.controller;


import Hwei.OBS.demo.config.WebSocketHandler;
import Hwei.OBS.demo.dto.FileUploadStatus;
import Hwei.OBS.demo.dto.R;
import Hwei.OBS.demo.dto.fileChunkDto;
import Hwei.OBS.demo.util.FileUtil;
import Hwei.OBS.demo.util.HweiOBSUtil;
import cn.hutool.crypto.SecureUtil;
import com.obs.services.model.PutObjectResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@RestController
@RequestMapping("huawei/obs")
public class ObsController {
    @Autowired
    private HweiOBSUtil hweiOBSUtil;

    @Autowired
    private WebSocketHandler webSocketHandler;
    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 文件上传
     * @param uploadFile
     * @return
     */
    @PostMapping("fileUpload")
    public R fileUpload(MultipartFile uploadFile){
        //讲文件转换为md5,实现唯一性
        String fileString = FileUtil.MultipartFileToString(uploadFile);
        String fileMd5 = SecureUtil.md5(fileString);
        //reids是否存在
        if (redisTemplate.hasKey(fileMd5)){
            //存在返回名称
            String  fileUrl = (String) redisTemplate.opsForValue().get(fileMd5);
            return R.ok().data(fileUrl);
        }else{
            //不存在上传并放入redis
            PutObjectResult putObjectResult = hweiOBSUtil.fileUpload(uploadFile, uploadFile.getOriginalFilename());
            if (putObjectResult!=null){
                redisTemplate.opsForValue().set(fileMd5,putObjectResult.getObjectUrl());
                return R.ok().data(putObjectResult.getObjectKey());
            }else{
                return R.error();
            }

        }
    }

    /**
     * 查询上传进度
     * @param fileName
     */
    @GetMapping("realFilePlan")
    public void redalFilePlan(String fileName) {
        FileUploadStatus fileUploadPlan = hweiOBSUtil.getFileUploadPlan(fileName);
        webSocketHandler.sendAllMessage(fileUploadPlan.getPct());
    }

    /**
     * 下载文件
     * @param request
     * @param response
     * @param fileName
     * @return
     */
    @GetMapping("fileDownload")
    public R fileDownload(HttpServletRequest request, HttpServletResponse response, String fileName){
        int i = hweiOBSUtil.fileDownload(request, response, fileName);
        if(i==0){
            return null;
        }
        return R.error();
    }



}

对应的MultipartFile转成String

package Hwei.OBS.demo.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

@Slf4j
@Configuration
public class FileUtil {
    /**
     * MultipartFile转成String
     * @param file
     * @return
     */
    public static String MultipartFileToString(MultipartFile file){
        InputStreamReader isr;
        BufferedReader br;
        StringBuilder txtResult = new StringBuilder();
        try {
            isr = new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8);
            br = new BufferedReader(isr);
            String lineTxt;
            while ((lineTxt = br.readLine()) != null) {
                txtResult.append(lineTxt);
            }
            isr.close();
            br.close();
            return txtResult.toString();
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }
}

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值