什么是 OSS?

OSS :Object Store Server 对象存储服务

阿里OSS 官网:https://help.aliyun.com/document_detail/31947.html?spm=a2c4g.11186623.6.1601.5a037a74VGSyuU

了解 OSS 就需要 知道 资源术语 也就是一些概念 下面搬运自 阿里oss 官网

OSS费用产生

  • 存储包:存储包 相当于一个云空间 100GB/月 大约11元
  • 外网下行流量包:下行流量包 相当于一个流量包 100GB/月 大约49元
  • 请求次数:没请求一次也需要计费,这个费用量很小,可忽略。

资源术语

中文英文说明
存储空间Bucket存储空间是您用于存储对象(Object)的容器,所有的对象都必须隶属于某个存储空间。
对象/文件Object对象是 OSS 存储数据的基本单元,也被称为OSS的文件。对象由元信息(Object Meta)、用户数据(Data)和文件名(Key)组成。对象由存储空间内部唯一的Key来标识。
地域Region地域表示 OSS 的数据中心所在物理位置。您可以根据费用、请求来源等综合选择数据存储的地域。详情请查看OSS已经开通的Region
访问域名EndpointEndpoint 表示OSS对外服务的访问域名。OSS以HTTP RESTful API的形式对外提供服务,当访问不同地域的时候,需要不同的域名。通过内网和外网访问同一个地域所需要的域名也是不同的。具体的内容请参见各个Region对应的Endpoint
访问密钥AccessKeyAccessKey,简称 AK,指的是访问身份验证中用到的AccessKeyId 和AccessKeySecret。OSS通过使用AccessKeyId 和AccessKeySecret对称加密的方法来验证某个请求的发送者身份。AccessKeyId用于标识用户,AccessKeySecret是用户用于加密签名字符串和OSS用来验证签名字符串的密钥,其中AccessKeySecret 必须保密。

首先 Endpoint 对应一个地区,一个地区都需要创建自己的Bucket ,在自己的Bucket中,添加自己的Object文件。

了解 这么多,就不用多废话了,直接 或者自己的 AccessKey、AccessKeySecret

强烈建议选择shanghai的Bucket,大城市的云服务,要比小城市新功能优先体验!

特别强调:Bucket有自己的权限:私有、公共读、公共读写。

  • 私有:仅自己上传、下载
  • 公共读:仅自己上传、任何都可以下载 正常都是用公共读
  • 公共读写:任何人都可以上传或者下载

日志管理也是一个非常重要的环节

在阿里云OSS控制台,点击Bucket列表,然后点击你的Bucket,然后点击日志管理,务必开启!

SpringBoot封装阿里OSS工具类

Maven 依赖

        <!--阿里OSS对象存储-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.10.2</version>
        </dependency>

Application.XXX 配置

OSS:
  AccessKeyId: 自己去申请
  AccessKeySecret: 自己去申请
  # Endpoint表示OSS对外服务的访问域名 查看更多 https://help.aliyun.com/document_detail/31837.html?spm=a2c4g.11186623.2.17.3a3d28baIOA2JD#concept-zt4-cvy-5db
  Endpoint:
    hangzhou: oss-cn-hangzhou.aliyuncs.com
    shanghai: oss-cn-shanghai.aliyuncs.com
    qingdao: oss-cn-qingdao.aliyuncs.com
    beijing: oss-cn-beijing.aliyuncs.com

工具类

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.*;


/**
 * 作者:臧立昆
 * 2020/9/15 14:35
 */

@Component
@Slf4j
public class AlibabaOSSUtils {

    @Value("${ALiYunOSS.AccessKeyId}")
    private static String AccessKeyId = "LTAI4GH34YPjbmqWypQguChZ";
    @Value("${ALiYunOSS.AccessKeySecret}")
    private static String AccessKeySecret = "EM6vfQHxx0KcxMBkBTEJorjOQmXiYs";
    @Value("${OSS.Endpoint.hangzhou}")
    private static String EndPoint = "oss-cn-hangzhou.aliyuncs.com";
    // 自己起个名字
    private static String Bucket = "";

    /**
     * 创建 一个 Bucket
     * @param BucketName 桶名
     * @return
     */
    public static Boolean CreateBucket(String BucketName){
        try{

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(EndPoint, AccessKeyId, AccessKeySecret);
        // 创建存储空间。
        ossClient.createBucket(BucketName);
        // 关闭OSSClient。
        ossClient.shutdown();
        log.info("创建Bucket"+BucketName+"成功");
        return true;
        } catch(Exception e){
            e.printStackTrace();
            log.info("创建Bucket"+BucketName+"失败 原因分析之一:可能是该Bucket名字被别人占用,更换名字试试");
        }
        return false;
    }

    /**
     * 上传文件 需要 下列参数
     * @param BucketName    桶名
     * @param FolderRoute   文件存储路径,因为 不能所有东西 都存储在一个桶文件夹下,到时候 桶里面文件乱糟糟的。相当于,分类了。
     * @param object        要存储的文件
     * @param objectName    存储后的文件
     * @return
     */
    public static Boolean UploadFile(String BucketName, String FolderRoute,byte[] object,String objectName){
        try{
            if(object.length <= 0){
                log.error("传输错误:文件为空");
                return false;
            }
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(EndPoint, AccessKeyId, AccessKeySecret);
            // 上传文件到指定的存储空间(bucketName)并将其保存为指定的文件名称(objectName)。
            long start = System.currentTimeMillis();
            if(FolderRoute != null){
            ossClient.putObject(BucketName, FolderRoute+"/"+objectName, new ByteArrayInputStream(object));
            }else {
            ossClient.putObject(BucketName, objectName, new ByteArrayInputStream(object));
            }
            // 关闭OSSClient。
            ossClient.shutdown();
            log.info("文件:"+objectName+"上传成功,时间为:{}ms",(System.currentTimeMillis() - start));
            return true;
        } catch(Exception e){
            e.printStackTrace();
            log.info("文件传输错误");
        }
        return false;
    }

    /**
     * 在桶 下创建文件夹 文件夹名称 就是 路由名称了
     * @param BucketName 桶的名字
     * @param FolderRoute   路径   实际路径就是 桶/路径/           为什么最后一个加“/” ? 因为不加“/”,OSS就会以为最后一个路径是个文件
     * @return
     */
    public static Boolean MakeDir(String BucketName, String FolderRoute){
        try{
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(EndPoint, AccessKeyId, AccessKeySecret);
            // 上传文件到指定的存储空间(bucketName)并将其保存为指定的文件名称(objectName)。
            long start = System.currentTimeMillis();
            if(FolderRoute != null){
                //拼接/的作用是 避免最后一个路径被Oss识别为文件
                ossClient.putObject(BucketName, FolderRoute+"/", new ByteArrayInputStream(new byte[0]));
            }else {
                log.info("文件夹创建失败");
            }
            // 关闭OSSClient。
            ossClient.shutdown();
            log.info("文件夹路径为"+BucketName+FolderRoute+"创建成功");
            return true;
        } catch(Exception e){
            e.printStackTrace();
            log.info("文件传输错误");
        }
        return false;
    }

    /**
     * 删除一个文件 需要知道文件所在 桶位置、路由路径、文件名称
     * @param BucketName    桶名称
     * @param FolderRoute   路由路径
     * @param objectName    文件名称
     * @return
     */
    public static Boolean DeleteObject(String BucketName,String FolderRoute,String objectName){
        try{
            if(objectName == null || objectName.length() <= 0 || objectName.isEmpty()){
                log.error("删除对象失败:对象名字格式不正确或区分大小写哦!");
                return false;
            }
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(EndPoint, AccessKeyId, AccessKeySecret);
            // 判断对象文件是否存在。
            if(ossClient.doesObjectExist(BucketName, FolderRoute+"/"+objectName)){
            // 删除文件。
                if(FolderRoute != null){
                ossClient.deleteObject(BucketName, FolderRoute+"/"+objectName);
                    log.info("文件:"+BucketName+FolderRoute+"/"+objectName+"删除成功");
                }else {
                    log.error("删除失败,文件夹路径有问题");
                }
            }else {
                log.error("删除失败,文件不存在");
                return false;
            }
            // 关闭OSSClient。
            ossClient.shutdown();
            return true;
        } catch(Exception e){
            e.printStackTrace();
            log.info("文件删除错误");
        }
        return false;
    }

    /**
     * 将文件转换成byte数组 因为传输必须要这个格式
     * @param
     * @return
     */
    public static byte[] File2byte(File tradeFile){
        byte[] buffer = null;
        try
        {
            FileInputStream fis = new FileInputStream(tradeFile);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1)
            {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
        return buffer;
    }


    /**
     * 测试 将 E盘下面的 mask.jpg 上传到 govbuy-trade/Live/ZLK/ 下 完整的名称是 abc.jpg  如果没有 相关路由, 他会自动生成出来
     * @param args
     */
    public static void main(String[] args) {
        //AlibabaOSSUtils.CreateBucket("adasdvc1218");
        UploadFile("govbuy-trade","Live/ZLK",AlibabaOSSUtils.File2byte(new File("E:\\mask.jpg")),"abc.jpg");
        //DeleteObject("adasdvc1218","ok");
        //MakeDir("govbuy-trade","B/B/C/");
        //DeleteObject("govbuy-trade","B","");
    }
}

测试

工具类中有个 main 方法,请再更换自己的 密钥账号 信息后,在E 盘下面创建 mask.jpg ,run 一下 main() 方法

特殊说明:
上述文章均是作者实际操作后产出。烦请各位,请勿直接盗用!转载记得标注原文链接:www.zanglikun.com
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取全部资料 ❤