在springboot项目中使用huaweiyunObs实现前端传递给后端的文件上传

1、存在的问题

因为华为云中的流式上传有单次5GB的限制,如果超过了需要分段上传,因此比较麻烦

2、解决方案

我们可以利用java中反射的机制拿到本地文件上传,这样就不会受到限制。

[!NOTE]

当我们前端传输一个文件到后端的时候,Tomcat服务器后自动存储在当地的Temp文件夹下,但是当请求结束的时候会自动删除因此我们只需要拿到本地的文件就可以上传到华为云的obs对象服务器

3、java文件

application.yml

huaweiyun:
  ak: 自己的ak
  sk: 自己的sk
  endPoint: https://obs.cn-north-4.myhuaweicloud.com
  bucketName: the name of bucket

HuaweiObsProperties.java

package com.sky.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "huaweiyun")
public class HuaweiObsProperties {
    private String ak;
    private String sk;
    private String endPoint;
    private String bucketName;
}

HuaweiObsUtil.java

package com.sky.utils;


import com.sky.properties.HuaweiObsProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.UUID;

import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.PutObjectRequest;


@Component
public class HuaweiObsUtil {
    private  String extenName;

    @Autowired
    private  HuaweiObsProperties huaweiObsProperties;

    public  String upload(MultipartFile uploadFile){
        //这里是我的ak
        String ak = huaweiObsProperties.getAk();
        //这里是我的sk
        String sk = huaweiObsProperties.getSk();
        String endPoint = huaweiObsProperties.getEndPoint();
        ObsClient obsClient = new ObsClient(ak, sk, endPoint);
        //获得想要上传的文件的路径
        //获得image的后缀名
        extenName = "." + uploadFile.getContentType().substring(uploadFile.getContentType().indexOf("/")+1);   // getContentType().indexOf("/");
        System.out.println(extenName);
        File file = null;
        try {
            Field part = uploadFile.getClass().getDeclaredField("part");
            part.setAccessible(true);
            Object localImage = part.get(uploadFile);
            Field location = localImage.getClass().getDeclaredField("fileItem");
            location.setAccessible(true);
            Object o =  location.get(localImage);
            Field tempFile = o.getClass().getDeclaredField("tempFile");
            tempFile.setAccessible(true);
            file =(File) tempFile.get(o);

        } catch (Exception e) {
            e.printStackTrace();
        }
        String url = obsUpload(obsClient,file);
        return url;
    }


    private String obsUpload(ObsClient obsClient, File file) {
        String renameFile = System.currentTimeMillis()+"";
        try {
            // 文件上传
            // localfile 为待上传的本地文件路径,需要指定到具体的文件名
            PutObjectRequest request = new PutObjectRequest();
            request.setBucketName("typora-ictures");

//            String fileNameWithoutExten = file.getName().substring
//                                            (file.getName().lastIndexOf("."));
            renameFile = UUID.randomUUID()+extenName;
            request.setObjectKey(renameFile);
            request.setFile(file);
            obsClient.putObject(request);
            System.out.println("putObject successfully");
        } catch (
                ObsException e) {
            System.out.println("putObject failed");
            // 请求失败,打印http状态码
            System.out.println("HTTP Code:" + e.getResponseCode());
            // 请求失败,打印服务端错误码
            System.out.println("Error Code:" + e.getErrorCode());
            // 请求失败,打印详细错误信息
            System.out.println("Error Message:" + e.getErrorMessage());
            // 请求失败,打印请求id
            System.out.println("Request ID:" + e.getErrorRequestId());
            System.out.println("Host ID:" + e.getErrorHostId());
            e.printStackTrace();
        } catch (Exception e) {
            System.out.println("putObject failed");
            // 其他异常信息打印
            e.printStackTrace();
        }
        return "https://" + huaweiObsProperties.getBucketName() + "." + huaweiObsProperties.getEndPoint().replace("https://", "") + "/"+renameFile;
    }

}
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐