Springboot实现华为云对象存储OBS文件上传下载



前言

OBS入门,注册账号、获取ak\sk、创建桶示例:https://support.huaweicloud.com/qs-obs/obs_qs_1000.html


一、OBS是什么?

对象存储服务(OBS)可以提供海量、安全、高可靠、低成本的数据存储能力,适用于大数据分析、静态网站托管、在线视频点播等场景。废话不多说,请允许我娓娓道来!

二、使用步骤

1.引入依赖

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

2.HuaweiyunOss工具类


package com.test.aliyunApi;

import com.obs.services.ObsClient;
import com.obs.services.model.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class HuaweiyunOss {

    @Value("${huaweiyun.obs.ak}")//ak
    private String ak;
    @Value("${huaweiyun.obs.sk}")//sk
    private String sk;
    @Value("${huaweiyun.obs.bucketName}")//桶名称
    private String bucketName;
    @Value("${huaweiyun.obs.endpoint}")//终端节点访问
    private String endpoint;

    /**
     * 上传文件--流式
     * @param fileName 上传文件名称
     * @param fileType 文件路径
     * @param is 文件流
     * @return
     */
    public boolean uploadFile(String fileName, FileType fileType, InputStream is) {
        ObsClient obsClient = null;
        try {
            String objectName = fileType.getType().concat("/").concat(fileName);
            obsClient = new ObsClient(ak, sk, endpoint);
            HeaderResponse response = obsClient.putObject(bucketName, objectName, is);
            // 可选:调用成功后,记录调用成功的HTTP状态码和服务端请求ID
            int statusCode = response.getStatusCode();
            if (200 == statusCode) {
                return true;
            }
            obsClient.close();
        } catch (IOException e) {
            log.info("文件上传失败:{}", e.getMessage(), e);
        }
        return false;
    }

    /**
     * 上传文件--字节数组
     * @param fileName 上传文件名称
     * @param fileType 文件路径
     * @param is 文件流
     * @return
     */
    public boolean uploadFileByte(String fileName, FileType fileType, byte[] is) {
        ObsClient obsClient = null;
        try {
            String objectName = fileType.getType().concat("/").concat(fileName);
            obsClient = new ObsClient(ak, sk, endpoint);
            HeaderResponse response = obsClient.putObject(bucketName, objectName, new ByteArrayInputStream(is));
            // 可选:调用成功后,记录调用成功的HTTP状态码和服务端请求ID
            int statusCode = response.getStatusCode();
            if (200 == statusCode) {
                return true;
            }
            obsClient.close();
        } catch (IOException e) {
            log.info("文件上传失败:{}", e.getMessage(), e);
        }
        return false;
    }

    /**
     * 下载文件
     * @param fileName 文件名称
     * @param fileType 文件路径
     * @return
     */
    public String getDownloadUrl(String fileName, FileType fileType) {
        ObsClient obsClient = null;
        obsClient = new ObsClient(ak, sk, endpoint);
        // URL有效期,3600秒.5分钟
        long expireSeconds = 3600L;
        String objectName = fileType.getType().concat("/").concat(fileName);
        TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, expireSeconds);
        request.setBucketName(bucketName);
        request.setObjectKey(objectName);
        TemporarySignatureResponse response = obsClient.createTemporarySignature(request);
        return response.getSignedUrl();
    }

    /**
     * 获取上传地址
     * @param fileName 文件名称
     * @param fileType 文件路径
     * @return
     */
    public String getUploadUrl(String fileName, FileType fileType) {
        try {
            // 创建ObsClient实例
            ObsClient obsClient = new ObsClient(ak, sk, endpoint);
            // URL有效期,3600秒
            long expireSeconds = 3600L;
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("Content-Type", "application/octet-stream");
            String objectName = fileType.getType().concat("/").concat(fileName);
            TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.PUT, expireSeconds);
            request.setBucketName(bucketName);
            request.setObjectKey(objectName);
            request.setHeaders(headers);
            TemporarySignatureResponse response = obsClient.createTemporarySignature(request);
            return response.getSignedUrl();
        } catch (Exception e) {
            log.error("获取上传地址异常:{}", e.getMessage(), e);
        }
        return null;
    }

    /**
     * 下载文件返回字节数组
     * @param fileName 文件名称
     * @param fileType 文件路径
     * @return
     */
    public byte[] downloadFile(String fileName, FileType fileType) {
        try {
            InputStream inputStream = downloadFileInputStream(fileName, fileType);
            byte[] bytes = IOUtils.toByteArray(inputStream);
            return bytes;
        } catch (Exception e) {
            log.error("下载文件异常:{}", e.getMessage(), e);
        }
        return null;
    }
    /**
     * 上传视频
     * @param fileName 文件名称
     * @param fileType 文件路径
     * @return
     */
    public boolean uploadFileVideo(String fileName, FileType fileType, InputStream is) {
        try {
            String objectName = fileType.getType().concat("/").concat(fileName);
            ObsClient obsClient = new ObsClient(ak, sk, endpoint);
            // 添加 ContentType (添加后可在浏览器中直接浏览,而非下载链接)
            obsClient.putObject(bucketName, objectName, is);
            obsClient.close();
            return true;
        } catch (Exception e) {
            log.error("上传视频文件异常:{}", e.getMessage(), e);
        }
        return false;
    }

    /**
     * 下载文件返回流式
     * @param fileName 文件名称
     * @param fileType 文件路径
     * @return
     */
    public InputStream downloadFileInputStream(String fileName, FileType fileType) {
        try {
            String objectName = fileType.getType().concat("/").concat(fileName);
            // 用户拿到STS临时凭证后,通过其中的安全令牌(SecurityToken)和临时访问密钥(AccessKeyId和AccessKeySecret)生成OSSClient。
            ObsClient obsClient = new ObsClient(ak, sk, endpoint);
            ObsObject obsObject = obsClient.getObject(bucketName, objectName);
            obsClient.close();
            return obsObject.getObjectContent();
        } catch (Exception e) {
            log.error("下载文件异常:{}", e.getMessage(), e);
        }
        return null;
    }


    public enum FileType {
        TEST("TEST", "测试")
        ;

        private String type;
        private String desc;

        FileType(String type, String desc) {
            this.type = type;
            this.desc = desc;
        }

        public String getType() {
            return type;
        }

        public String getDesc() {
            return desc;
        }
    }
}

3.上传下载测试

	@Autowired
    private HuaweiyunOss huaweiyunOss;
	/**
	 * 上传图片并下载返回预览地址
	 * @param file
	 * @return
	 * @throws IOException
	*/
	@PostMapping("/pic")
	@ApiOperation(value = "上传图片", notes = "上传图片")
	public Response<?> pic(MultipartFile file) throws IOException {
		String fileName = file.getOriginalFilename();
		boolean isOk = huaweiyunOss.uploadFile(fileName, HuaweiyunOss.FileType.TEST, file.getInputStream());
		String downloadUrl = huaweiyunOss.getDownloadUrl(fileName, HuaweiyunOss.FileType.TEST);
		Map<String,Object> map = new HashMap<>();
		map.put("downloadUrl",downloadUrl);
		map.put("fileName",fileName);
		return isOk ? Response.success(map) : Response.error("文件上传失败");
	}
	/**
	 * 上传视频并下载返回预览地址
	 * @param file
	 * @return
	 * @throws IOException
	*/
	@PostMapping("/video")
	@ApiOperation(value = "上传视频", notes = "上传视频")
	public Response<?> video(MultipartFile file) throws IOException {
		String fileName = file.getOriginalFilename();
		boolean isOk = huaweiyunOss.uploadFileVideo(fileName, HuaweiyunOss.FileType.TEST, file.getInputStream());
		String downloadUrl = huaweiyunOss.getDownloadUrl(fileName, HuaweiyunOss.FileType.TEST);
		Map<String,Object> map = new HashMap<>();
		map.put("downloadUrl",downloadUrl);
		map.put("fileName",fileName);
		return isOk ? Response.success(map) : Response.error("文件上传失败");
	}
	/**
	 * 获取上传地址
	 * @param picName
	 * @return
	 * @throws IOException
	*/
	 String videoUploadUrl = huaweiyunOss.getUploadUrl(picName, HuaweiyunOss.FileType.TEST);
	/**
     * 下载文件返回字节数组
     * @param fileName 文件名称
     * @param fileType 文件路径
     * @return
    */
    public byte[] downloadFile(String fileName, FileType fileType) {
        try {
            InputStream inputStream = downloadFileInputStream(fileName, fileType);
            byte[] bytes = IOUtils.toByteArray(inputStream);
            return bytes;
        } catch (Exception e) {
            log.error("下载文件异常:{}", e.getMessage(), e);
        }
        return null;
    }


总结

 OBS提供了四种存储类别:标准存储、低频访问存储、归档存储、深度归档存储(受限公测中),从而满足客户业务对存储性能、成本的不同诉求。自我感觉喝OSS用法一样,只是调用的方法不一样而已,欢迎探讨!
    1、标准存储访问时延低和吞吐量高,因而适用于有大量热点文件(平均一个月多次)或小文件(小于1MB),且需要频繁访问数据的业务场景,例如:大数据、移动应用、热点视频、社交图片等场景。
    2、低频访问存储适用于不频繁访问(平均一年少于12次)但在需要时也要求快速访问数据的业务场景,例如:文件同步/共享、企业备份等		  
    场景。与标准存储相比,低频访问存储有相同的数据持久性、吞吐量以及访问时延,且成本较低,但是可用性略低于标准存储。
    3、归档存储适用于很少访问(平均一年访问一次)数据的业务场景,例如:数据归档、长期备份等场景。归档存储安全、持久且成本极低,可以用来替代磁带库。为了保持成本低廉,数据取回时间可能长达数分钟到数小时不等。
    4、深度归档存储适用于长期不访问(平均几年访问一次)数据的业务场景,其成本相比归档存储更低,但相应的数据取回时间将更长,一般为数小时。
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐