云存储解决方案-华为云OBS存储服务案例

需求


我们在日常的业务需求中,会大量的遇到视频,图片,文件等等的存储需求,目前接触到工具有:minio,obs,ftp等等。

本文主要介绍:华为云对象存储服务(Object Storage Service,简称OBS)为您提供基于网络的数据存取服务。使用OBS,您可以通过网络随时存储和调用包括文本、图片、音频和视频等在内的各种非结构化数据文件。

步骤

1.开通obs并官方文档配置obs。
2.参考官方api,在springboot集成obs。

一、开通obs并官方文档配置obs

登录华为云官网,在产品标签处直接搜索obs。

 具体购买流程和购买后的配置请参考文档:

https://support.huaweicloud.com/sdk-java-devg-obs/obs_21_0001.html
华为云官方文档


二、springboot集成obs

1.创建测试工程,引入依赖。


2.在springBoot中集成OBS。

将密钥、 地址、桶名配置到application-dev.yml文件中,方便后期的更改。

创建对应的配置文件中华为账户对应的实体类。

分离出初始化obs方法。

结合官方文档封装自己的obs工具类。

package com.richstonedt.smartcity.xaytsccommoncs.util;
import com.obs.services.ObsClient;
import com.obs.services.ObsConfiguration;
import com.obs.services.exception.ObsException;
import com.obs.services.internal.ObsService;
import com.obs.services.model.*;
import com.richstonedt.smartcity.xaytsccommoncs.annotation.ObsClientAnnotation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * <b><code>ObsUtil</code></b>
 * <p/>
 * Description OBS工具类
 * <p/>
 * <b>Creation Time:</b> 2022/3/29 15:56:45
 *
 * @author tangjiahuan
 * @since xaytsc-common-be
 */
public class ObsUtil {
    private final static Logger logger = LoggerFactory.getLogger(ObsService.class);

    private ObsClient obsClient;
    private String bucketName;
    private String bucketLoc;
    private ObsConfiguration config;

    public ObsUtil() {
    }

    public ObsUtil(String bucketName, String bucketLoc, ObsConfiguration config) {
        this.bucketName = bucketName;
        this.bucketLoc = bucketLoc;
        this.config = config;
    }

    public ObsUtil( String bucketLoc, ObsConfiguration config) {
        this.bucketLoc = bucketLoc;
        this.config = config;
    }

    /**
     * 查询所有桶
     *
     * @return 桶的列表
     */
//    @ObsClientAnnotation
    public List<ObsBucket> listBuckets() {
        ListBucketsRequest request = new ListBucketsRequest();
        request.setQueryLocation(true);
        List<ObsBucket> buckets = obsClient.listBuckets(request);
        return buckets;
    }

    /**
     * 桶的新增
     *
     * @param bucketName 桶的名称
     * @return 桶对象信息
     */
//    @ObsClientAnnotation
    public ObsBucket createBucket(String bucketName) {
        ObsBucket obsBucket = new ObsBucket(bucketName, bucketLoc);
        obsBucket.setBucketName(bucketName);
        return obsClient.createBucket(obsBucket);
    }

    /**
     * 桶的删除
     *
     * @param bucketName 桶的名称
     * @return 响应对象
     */
//    @ObsClientAnnotation
    public HeaderResponse deleteBucket(String bucketName) {
        return obsClient.deleteBucket(bucketName);
    }

    /**
     * 设置桶内指定前缀的文件对象 过期时间
     *
     * @param prefix         什么前缀的文件过期(比如/tmp)
     * @param expirationDays 几天后过期
     */
    @ObsClientAnnotation
    public HeaderResponse setLiftConfig(String prefix, Integer expirationDays) {
        LifecycleConfiguration config = new LifecycleConfiguration();
        LifecycleConfiguration.Rule rule = config.new Rule();
        rule.setEnabled(true);
        //过期规则名称
        rule.setId(String.valueOf(UUID.randomUUID()));
        rule.setPrefix(prefix);
        LifecycleConfiguration.Expiration expiration = config.new Expiration();
        // 指定满足前缀的对象创建x天后过期
        expiration.setDays(expirationDays);
        LifecycleConfiguration.NoncurrentVersionExpiration noncurrentVersionExpiration = config.new NoncurrentVersionExpiration();
        // 指定满足前缀的对象成为历史版本x天后过期
        noncurrentVersionExpiration.setDays(expirationDays);
        rule.setNoncurrentVersionExpiration(noncurrentVersionExpiration);
        config.addRule(rule);
        return obsClient.setBucketLifecycle(bucketName, config);
    }

    /**
     * 查询桶的所有对象
     *
     * @return 桶内对象集合(关键属性getObjectKey)
     */
//    @ObsClientAnnotation
    public ObjectListing listObjects() {
        ObjectListing objects = obsClient.listObjects(bucketName);
        return objects;
    }

    /**
     * 上传对象时指定预定义访问策略为公共读(很重要)
     *
     * @param objectKey   对象的key
     * @param inputStream 要上传的文件流
     * @return 响应对象
     */
//    @ObsClientAnnotation
    public PutObjectResult putObjectAndSetPreAccessStrategy(String objectKey, InputStream inputStream) {
        PutObjectRequest request = new PutObjectRequest();
        request.setBucketName(bucketName);
        //对象的key 如:  objectname1/text
        request.setObjectKey(objectKey);
        request.setInput(inputStream);
        //设置对象访问权限为公共读
        request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
        return obsClient.putObject(request);
    }

    /**
     * 上传对象时指定预定义访问策略为公共读(很重要)
     * @param isImage 是否为图片
     * @param objectKey   对象的key
     * @param file 要上传的文件
     * @return 响应对象
     */
//    @ObsClientAnnotation
    public PutObjectResult putObjectAndSetPreAccessStrategy(String objectKey, File file,Integer isImage) {
        PutObjectRequest request = new PutObjectRequest();
        request.setBucketName(bucketName);
        //对象的key 如:  objectname1/text
        request.setObjectKey(objectKey);
        request.setFile(file);
        //设置元数据 isImage  0:1:文件
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.addUserMetadata("isImage", isImage.toString());
        request.setMetadata(metadata);
        //图片设置为公共读
       /* if(isImage == 0){
            //设置对象访问权限为公共读
            request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
        }*/
        return obsClient.putObject(request);
    }

    /**
     * 上传某个对象并设置对象自定义元数据
     *
     * @param objectKey   要上传的key
     * @param metadata    元数据对象
     * @param inputStream 要上传的文件流
     * @return 上传结果
     * //  ObjectMetadata metadata = new ObjectMetadata();
     * //  metadata.addUserMetadata("property1", "property-value1");
     * //  metadata.getMetadata().put("property2", "property-value2");
     * //  C:\\Users\\hufanglei\\Pictures\\timg.jpg"
     */
//    @ObsClientAnnotation
    public PutObjectResult putObjectAndSetMeta(String objectKey, ObjectMetadata metadata, InputStream inputStream) {
        return obsClient.putObject(bucketName, objectKey, inputStream, metadata);
    }

    /**
     * 获取某个对象
     *
     * @param objectKey 对象的key
     * @return 对象的信息
     */
//    @ObsClientAnnotation
    public ObsObject getObject(String objectKey) {
        return obsClient.getObject(bucketName, objectKey, null);
    }

    /**
     * 获取某个对象的流
     *
     * @param objectKey 对象的key
     * @return 对象的流
     */
//    @ObsClientAnnotation
    public InputStream getObjectInpuStream(String objectKey) {
        ObsObject obsObject = obsClient.getObject(bucketName, objectKey, null);
        return obsObject.getObjectContent();
    }

    /**
     * 查询对象元数据(查询某个对象的具体信息)
     *
     * @param objectKey 要查询的key
     * @return 对象元数据
     */
//    @ObsClientAnnotation
    public ObjectMetadata getObjectMetadata(String objectKey) {
        //获取对象元数据
        return obsClient.getObjectMetadata(bucketName, objectKey, null);
    }

    /**
     * 拷贝对象(也可以从一个桶拷贝到另一个桶,这里目前桶和原始文件桶都设置成了配置文件中的桶)
     *
     * @param sourceObjectKey 原始key
     * @param destObjectKey   目标key
     * @return 响应结果
     */
//    @ObsClientAnnotation
    public CopyObjectResult copyObject(String sourceObjectKey, String destObjectKey) {
        String sourceBucketName = bucketName;
        String destBucketName = bucketName;
        return obsClient.copyObject(sourceBucketName, sourceObjectKey, destBucketName, destObjectKey);
    }

    /**
     * 删除单个对象
     *
     * @param objectKey 要删除的key
     * @return 响应结果
     */
//    @ObsClientAnnotation
    public DeleteObjectResult deletObj(String objectKey) {
        return obsClient.deleteObject(bucketName, objectKey);
    }

    /**
     * 删除 对象
     * @param objectKey 对象key
     * @return 是否删除成功
     */
    public boolean deleteObject(String objectKey){
        if(obsClient.doesObjectExist(bucketName,objectKey)){
            obsClient.deleteObject(bucketName,objectKey);
            return true;
        }
        return false;
    }

    public boolean isExistObject(String bucketName,String objectKey){
       return obsClient.doesObjectExist(bucketName,objectKey);
    }
    /**
     * 下载某个对象到本地
     *
     * @param objectKey     对象的key
     * @param localFilePath 本地文件路径
     * @throws ObsException
     * @throws IOException
     */
//    @ObsClientAnnotation
    public void downloadToLocalFile(String objectKey, String localFilePath) throws ObsException, IOException {
        File localFile = new File(localFilePath);
        if (!localFile.getParentFile().exists()) {
            localFile.getParentFile().mkdirs();
        }
        ObsObject obsObject = obsClient.getObject(bucketName, objectKey, null);
        ReadableByteChannel rchannel = Channels.newChannel(obsObject.getObjectContent());
        ByteBuffer buffer = ByteBuffer.allocate(4096);
        WritableByteChannel wchannel = Channels.newChannel(new FileOutputStream(new File(localFilePath)));
        while (rchannel.read(buffer) != -1) {
            buffer.flip();
            wchannel.write(buffer);
            buffer.clear();
        }
        rchannel.close();
        wchannel.close();
    }

    /**
     * 创建一个文件夹,必须带有/后缀
     *
     * @param keySuffixWithSlash1 文件夹名称(必须带有/后缀)
     * @return 响应对象
     */
//    @ObsClientAnnotation
    public PutObjectResult createEmptyFolder(String bucketName,String keySuffixWithSlash1) {
        return obsClient.putObject(bucketName, keySuffixWithSlash1, new ByteArrayInputStream(new byte[0]));
    }


    /**
     * 判断对象是否是文件夹
     * @param keySuffixWithSlash1 文件夹名: 如:   "MyObjectKey1/"
     * @return 布尔值
     */
//    @ObsClientAnnotation
    public boolean isEmptyFolder(String keySuffixWithSlash1)  {
        ObsObject object = obsClient.getObject(bucketName, keySuffixWithSlash1, null);
        if (object != null) {
            return object.getMetadata().getContentLength() == 0L;
        }
        return false;
    }

    /**
     * 列举某个文件夹下的所有对象
     *
     * @param folderPrefix 件夹名(必须/结尾)
     * @return 对象集合
     */
//    @ObsClientAnnotation
    public ObjectListing listObjectsByFolder(String folderPrefix) {
        ListObjectsRequest request = new ListObjectsRequest(bucketName);
        // 设置文件夹对象名"dir/"为前缀
        // request.setPrefix("dir/");
        request.setPrefix(folderPrefix);
        //列举文件个数
        request.setMaxKeys(1000);
        ObjectListing result;
        do {
            result = obsClient.listObjects(request);
            for (ObsObject obsObject : result.getObjects()) {
                logger.info("\t" + obsObject.getObjectKey());
                logger.info("\t" + obsObject.getOwner());
            }
            request.setMarker(result.getNextMarker());
        } while (result.isTruncated());
        return result;
    }

    /**
     * 删除某个文件夹下的所有对象
     *
     * @param folderPrefix 文件夹名(必须/结尾)
     * @return 是否删除成功
     */
//    @ObsClientAnnotation
    public boolean deleteListObjectsByFolder(String folderPrefix) {
        ListObjectsRequest request = new ListObjectsRequest(bucketName);
        // 设置文件夹对象名"/xx/xxx/"为前缀
        request.setPrefix(folderPrefix);
        //列举文件个数
        request.setMaxKeys(1000);
        ObjectListing result;
        do {
            result = obsClient.listObjects(request);
            for (ObsObject obsObject : result.getObjects()) {
                logger.info("\t" + obsObject.getObjectKey());
                logger.info("\t" + obsObject.getOwner());
                //执行删除
                obsClient.deleteObject(bucketName, obsObject.getObjectKey());
            }
            request.setMarker(result.getNextMarker());
        } while (result.isTruncated());
        return true;
    }

    /**
     * 批量删除
     * @param objectKeys 文件key集合
     * @param bucketName 桶名
     * @return 删除结果
     */
    public DeleteObjectsResult deleteBatch(String bucketName,List<String> objectKeys){
        DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest();
        for (String key:objectKeys) {
            deleteObjectsRequest.addKeyAndVersion(key);
        }
        deleteObjectsRequest.setBucketName(bucketName);
        return obsClient.deleteObjects(deleteObjectsRequest);
    }

    public void outputErrorInfo(ObsException e){
        logger.info("HTTP Code: " + e.getResponseCode());
        logger.info("Error Code:" + e.getErrorCode());
        logger.info("Error Message: " + e.getErrorMessage());
        logger.info("Request ID:" + e.getErrorRequestId());
        logger.info("Host ID:" + e.getErrorHostId());
    }

}

调用OBS工具类以及方法,将上传的文件传入到华为云OBS中。

上传obs成功后的资源如何如何访问。

测试​​​​​​​​​​​​​​

查看obs中是否上传成功。

查看obs上传成功后的返回地址是否可以访问。


- End-
收藏点赞转发,是对我最大的鼓励。您的支持就是我坚持下去的最大动力!

另外我的公众号也在同步更新文章。后续会更新SpringCloud alibaba开发实战、Elasticsearch+Logstash+Kibana实战、nginx+ssl+域名实战、日常开发问题闭坑集锦等等....


 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
华为OBS是华为开放存储服务的一种云存储解决方案,它提供了可靠、安全、持久的对象存储服务,能够满足用户在云端存储和处理各种数据的需求。 Spring Boot是一个开源的Java框架,它能够快速地构建独立的、生产级别的应用程序。使用Spring Boot可以简化Java应用的开发过程,并且提供了自动配置和约定大于配置的原则。开发人员可以通过Spring Boot快速集成和使用华为OBS,以便于在应用程序中实现高效的对象存储。 结合华为OBSSpring Boot,我们可以通过以下方式实现丰富的云存储功能: 1. 配置OBS客户端:在Spring Boot配置文件中设置OBS的访问密钥、终端节点等信息,以便于程序能够连接和使用OBS服务。 2. 使用OBS SDK:在Spring Boot应用中使用华为OBS提供的Java SDK,通过编写代码调用OBS的API实现对象的上传、下载、删除等操作。 3. 实现文件上传和下载:通过Spring Boot的文件上传功能,将用户上传的文件保存到OBS中,然后提供下载链接给用户进行文件的下载。 4. 实现图片处理:结合Spring Boot提供的图像处理功能,可以将用户上传的图片保存到OBS中,并进行缩放、裁剪、水印等处理操作,然后再将处理后的图片返回给用户。 总之,华为OBSSpring Boot的结合,能够为开发者提供方便、高效的云存储解决方案,帮助开发者快速构建安全可靠的应用程序,并且在处理大量数据和文件时能够具备良好的性能和可扩展性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值