对象存储OSS 服务搭建

前言

最近在练习写一个前后端分离项目,第一个完整的功能已经接近尾声,就差图片上传了,正好记录一下搭建OSS服务的过程!

什么是对象存储 OSS

摘自阿里云对象存储 OSS文档:

https://help.aliyun.com/document_detail/31817.html?spm=a2c4g.11174283.2.5.6f6d7da25wwxU3

海量、安全、低成本、高可靠的云存储服务,提供99.9999999999%的数据可靠性。使用RESTful API 可以在互联网任何位置存储和访问,容量和处理能力弹性扩展,多种存储类型供选择全面优化存储成本。

OSS 具有与平台无关的 RESTful API 接口,您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。

视频

观看以下视频,快速了解 OSS。

计费规则

https://www.aliyun.com/price/product?spm=a2c4g.11186623.2.30.578865d3hAKfyD#/oss/detail

学习的话充个几块钱即可

开通OSS

开通对象存储

开通成功

OSS管理后台

创建Buckect

  • Buckect可以想象成一个数据库,一般一个项目对应一个Buckect即可

进入Bucket列表

  • 这里的读写权限我们一般选择公共读,让资源在任何地方都可以访问,而写操作通过我们的服务带上身份验证进行
  • 其他的参数可能和价格挂钩,按需选择即可

创建Bucket

  • 创建完成后可以看到概览页面中有两个重要的地址:地域节点和Bucket域名

地域节点、Bucket域名

创建目录

  • 这里创建目录是用于区分不同类型的文件

创建目录

  • 上传一个文件测试一下,这个URL就是我们后面要拼接的图片路径,可以用来参考

上传图片测试

AccessKey安全

创建用户

  • 我们要对OSS进行远程写操作,必须要创建AccessKey,阿里云提示我们用子用户创建AccessKey比较安全

    点击Access Key

使用子用户

创建用户,选择编程访问

  • 注意:创建后记得保存AccessKeySecret,下次再进来就没了

创建完成

创建用户组

  • 用户组用于将统一的权限集合分配给多个用户

    创建用户组

  • 创建好用户组之后,给用户组分配权限AliyunOSSFullAccess

    AliyunOSSFullAccess

  • 接着将刚刚创建的用户添加进组

    添加用户

总结

一系列OSS管理后台的操作都玩了一遍,到这里我们搜集到了几个信息,用于对接OSS

Bucket: hetonghao

地域节点: oss-cn-shenzhen.aliyuncs.com

Bucket域名: hetonghao.oss-cn-shenzhen.aliyuncs.com

用户名: hetonghao@1654216698096004.onaliyun.com

AccessKeyID: LTAI4FgBBEeeRTMkVVFkKFEA

AccessKeySecret: ------------------------

对接OSS SDK

参考官方Java SDK文档

https://help.aliyun.com/document_detail/84781.html?spm=5176.8466032.0.0.f6311450ACtR4P

添加pom依赖

<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.8.0</version>
</dependency>

编写OSS代码

  • application.yml 配置

    oss:
    aliyun:
    imagesHost: images
    endPoint: oss-cn-shenzhen.aliyuncs.com
    bucket: hetonghao
    accessKeyId: LTAI4FgBBEeeRTMkVVFkKFEA
    accessKeySecret: --------------------
  • OssConfigProperties 用于读取配置

    package cn.hetonghao.oss.config;

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

    /**
    * oss配置属性
    *
    * @author HeTongHao
    * @since 2020/4/12 14:35
    */
    @Data
    @ConfigurationProperties(prefix = "oss.aliyun")
    public class OssConfigProperties {
    private String imagesHost;
    /**
    * 地域节点
    */
    private String endPoint;
    private String bucket;
    private String accessKeyId;
    private String accessKeySecret;
    }
  • Service

    package cn.hetonghao.oss.service;

    import com.aliyun.oss.model.Bucket;
    import org.springframework.web.multipart.MultipartFile;

    /**
    * oss 文件管理
    *
    * @author HeTongHao
    * @since 2020/4/12 14:32
    */
    public interface IOssFileService {
    /**
    * 上传文件
    *
    * @param multipartFile
    * @return
    */
    String upload(MultipartFile multipartFile);

    /**
    * 创建Bucket
    *
    * @param bucketName
    * @return
    */
    Bucket createBucket(String bucketName);
    }
  • Service impl

    package cn.hetonghao.oss.service.impl;

    import cn.hetonghao.oss.config.OssConfigProperties;
    import cn.hetonghao.oss.service.IOssFileService;
    import com.aliyun.oss.OSS;
    import com.aliyun.oss.OSSClientBuilder;
    import com.aliyun.oss.model.Bucket;
    import com.aliyun.oss.model.CannedAccessControlList;
    import com.aliyun.oss.model.CreateBucketRequest;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.stereotype.Service;
    import org.springframework.web.multipart.MultipartFile;

    import java.io.IOException;
    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    import java.util.Optional;
    import java.util.UUID;

    /**
    * oss 文件管理实现
    *
    * @author HeTongHao
    * @since 2020/4/12 14:34
    */
    @Service
    @EnableConfigurationProperties(OssConfigProperties.class)
    public class OssFileServiceImpl implements IOssFileService {
    @Autowired
    private OssConfigProperties ossConfigProperties;

    /**
    * 创建OSSClient实例
    *
    * @return
    */
    private OSS createOssClient() {
    return new OSSClientBuilder().build(ossConfigProperties.getEndPoint()
    , ossConfigProperties.getAccessKeyId(), ossConfigProperties.getAccessKeySecret());
    }

    @Override
    public String upload(MultipartFile multipartFile) {
    String uploadPath = null;
    OSS ossClient = null;
    try {
    // 创建OSSClient实例。
    ossClient = createOssClient();
    // 对文件重命名
    String oriName = Optional.ofNullable(multipartFile.getOriginalFilename()).orElse("");
    // 文件按日期分类
    String filePath = DateTimeFormatter.ofPattern("yyyy/MM/dd").format(LocalDate.now());
    String fileName = UUID.randomUUID().toString();
    String fileSuffix = oriName.substring(oriName.indexOf("."));
    String fileNewName = fileName + fileSuffix;
    String fileUrl = ossConfigProperties.getImagesHost() + '/' + filePath + '/' + fileNewName;
    // 上传一个对象
    ossClient.putObject(ossConfigProperties.getBucket(), fileUrl, multipartFile.getInputStream());
    // 最后的访问路径 = Bucket+EndPoint+fileFullUrl
    uploadPath = "https://" + ossConfigProperties.getBucket() + "." + ossConfigProperties.getEndPoint()
    + "/" + fileUrl;
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    if (ossClient != null) {
    // 关闭OSSClient。
    ossClient.shutdown();
    }
    }
    return uploadPath;
    }

    @Override
    public Bucket createBucket(String bucketName) {
    Bucket bucket = null;
    OSS ossClient = null;
    try {
    // 创建OSSClient实例。
    ossClient = createOssClient();
    CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
    //设置成公共读
    createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
    //创建
    bucket = ossClient.createBucket(createBucketRequest);
    } finally {
    if (ossClient != null) {
    // 关闭OSSClient。
    ossClient.shutdown();
    }
    }
    return bucket;
    }
    }
  • controller

    /**
    * 文件管理Controller
    *
    * @author HeTongHao
    * @since 2020/4/12 15:15
    */
    @Api("文件管理")
    @RestController
    @RequestMapping("file")
    public class FileController {
    @Autowired
    private IOssFileService ossFileService;

    @ApiOperation("文件上传")
    @PostMapping("upload")
    public SingleResponse<String> upload(@RequestBody MultipartFile file) {
    return new SingleResponse<String>()
    .setData(ossFileService.upload(file));
    }
    }

测试

上传文件

  • 访问swagger页面调用api

成功返回上传地址

管理后台

创建Bucket

  • 执行单元测试

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = OssServerMain.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    public class OssTest {
    @Autowired
    private IOssFileService ossFileService;

    @Test
    public void testCreateBucket() {
    System.out.println(ossFileService.createBucket("hetonghao-test-bucket"));
    }
    }

    输出结果

管理后台Bukect列表

总结

  • 至此基础的Java OSS 服务已经搭建完毕,还可以继续扩展实现,比如:删除文件、给文件进行精准的权限控制等等。
  • 其它语言接入OSS如Python、Go官方都有对应的Sdk。
  • 对象存储不止于OSS,其它服务商如腾讯云的COS、七牛云的KODO等都可以实现!
文章作者: 何同昊
文章链接: http://hetonghao.cn/2020/04/OSS服务搭建/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 何同昊 Blog
支付宝超级火箭🚀
微信超级火箭🚀