• 使用SpringBoot将图片上传至阿里云OSS


    一. 对象存储OSS

    1. 什么是OSS?

    官方的解释是这样的:阿里云对象存储OSS(Object Storage Service)是一款海量、安全、低成本、高可靠的云存储服务,提供99.9999999999%(12个9)的数据持久性,99.995%的数据可用性。
    官网:对象存储OSS

    2. 为什么要使用OSS?

    作者认为主要是方便项目上线后的文件业务的处理,试想一下:大多数人都不会把自己电脑直接上当本地服务器上直接上线项目吧,如果用云服务器访问量大的话又有点占空间,也无法对图片进行加密,但我们用到OSS存储文件就可以解决大部分问题了

    二. 开通 OSS

    第一步,登录阿里云官网,搜索“OSS”关键字,进入 OSS 产品页。
    在这里插入图片描述

    第二步,购买套餐
    在这里插入图片描述

    新人好像有优惠活动,笔者没看到花钱买的觉得血亏(虽然只有几块)

    在这里插入图片描述

    第三步,进入 OSS 管理控制台,点击Bucket 列表,点击创建 Bucket
    在这里插入图片描述

    在这里插入图片描述

    注意:读写权限为“公共读”,也就是允许互联网用户访问云空间上的图片。

    第四步:确认就行

    三、SpringBoot 整合 OSS 实现文件上传

    1. 在 pom.xml 文件中添加 OSS 的依赖。
    <dependency>
        <groupId>com.aliyun.ossgroupId>
        <artifactId>aliyun-sdk-ossartifactId>
        <version>3.14.0version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    2. 在 application.yml 文件中添加 OSS 配置项。
    aliyun:
      oss:
        # oss对外服务的访问域名
        endpoint: oss-cn-guangzhou.aliyuncs.com
        # 访问身份验证中用到用户标识(填自己的)
        accessKeyId: LTAI5xxxxxxxxxx
        # 用户用于加密签名字符串和oss用来验证签名字符串的密钥(填自己的)
        accessKeySecret: xxxxxxxx
        # oss的存储空间
        bucketName: baridhu
        # 上传文件大小(M)
        maxSize: 3
        # 上传文件夹路径前缀
        dir:
          prefix: helloworld/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    补充:如何获取自己的用户标识和密钥

    1. 把鼠标移动到自己头像位置会出悬浮框,我们选择AccessKey管理
    在这里插入图片描述
    2. 创建AccessKey
    在这里插入图片描述
    在这里插入图片描述
    剩下的按着操作就行了,不再赘叙了

    3. 创建配置类OssClientConfig.java
    @Configuration
    public class OssClientConfig {
        @Value("${aliyun.oss.endpoint}")
        String endpoint ;
        @Value("${aliyun.oss.accessKeyId}")
        String accessKeyId ;
        @Value("${aliyun.oss.accessKeySecret}")
        String accessKeySecret;
    
        @Bean
        public OSSClient createOssClient() {
            return (OSSClient)new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    其功能是实现图片上传至OSS,其内置操作有兴趣的可以自己看源码

    4. 文件上传接口

    /**
     * @author hj(BaridHu)
     */
    
    @Slf4j
    @Api(value = "file", tags = {"文件控制层"})
    @RequestMapping("file")
    @RestController
    @LoginClassAnnotation
    public class FileController {
    
        @Value("${aliyun.oss.maxSize}")
        private int maxSize;
    
        @Value("${aliyun.oss.bucketName}")
        private String bucketName;
    
        @Value("${aliyun.oss.dir.prefix}")
        private String dirPrefix;
    
        @Resource
        private OSSClient ossClient;
    
        @Resource
        private FileService fileService;
    
        @ApiOperation(value = "文件上传OSS接口")
        @PostMapping("upload")
        public RestResponse uploadToOSS(@ApiParam(value = "文件名", required = true) @RequestParam("photo") MultipartFile file) {
            String url = "";
            try {
                InputStream inputStream = file.getInputStream();
                String objectName =  getObjectName(file);
                // 创建PutObject请求。
                ossClient.putObject(bucketName, objectName, inputStream);
                url = formatPath(objectName);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return RestResponse.ok(url);
        }
    
        private String getObjectName(MultipartFile file) {
            // 文件后缀
            String suffixName = Objects.requireNonNull(file.getOriginalFilename()).substring(file.getOriginalFilename().lastIndexOf("."));
            String fileName = SpringContextUtils.getContext().getBean(SnowFlakeUtils.class).nextId() + suffixName;
            // 文件类型:1-图片,2-音频,3-视频
            String fileType = FileUtils.getFileType(suffixName);
            // 完整路径
            String objectName = "";
            switch (fileType) {
                case "1":
                    objectName = dirPrefix + "images/" + DateUtil.today() + "/" + fileName;
                    break;
                case "2":
    
                    objectName = dirPrefix + "audio/" + DateUtil.today() + "/" + fileName;
                    break;
                case "3":
                    objectName = dirPrefix +"videos/" + DateUtil.today() + "/" + fileName;
                    break;
                default:
                    break;
            }
            return objectName;
        }
    
        private String formatPath(String objectName){
            return "https://" + bucketName + "." + ossClient.getEndpoint().getHost() + "/" + objectName;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    补充1: SpringContextUtils.getContext().getBean(SnowFlakeUtils.class).nextId() 是利用雪花算法生成全局唯一的ID值,源于Twitter,能很好的保证ID值不重复,有兴趣的自己可以研究研究,有时间我也会出一期关于雪花算法的文章,这里大家可以使用UUID来代替

    String fileName = UUID.randomUUID().toString() + suffixName;
    
    • 1

    补充2: FileUtils工具类

    /**
     * @author hj(BaridHu)
     */
     
    @Component
    public class FileUtils {
    
        public static final String TYPE_JPG = ".jpg";
    
        public static final String TYPE_GIF = ".gif";
    
        public static final String TYPE_PNG = ".png";
    
        public static final String TYPE_BMP = ".bmp";
    
        public static final String TYPE_MP3 = ".mp3";
    
        public static final String TYPE_WAV = ".wav";
    
        public static final String TYPE_M4A = ".m4a";
    
        public static final String TYPE_MP4 = ".mp4";
    
        public static final String TYPE_UNKNOWN = "unknown";
    
    
        public static boolean delFile(File file) {
            if (file.exists()) {
                String name = file.getName();
                file.delete();
                System.out.println("文件 [" + name + "] 已经删除!");
                return true;
            }
            return false;
        }
    
        /**
         * 获取文件类型
         * type:1-图片,2-音频,3-视频
         *
         * @return {@link String}
         */
        public static String getFileType(String suffixName) {
            String type = null;
            switch (suffixName) {
                case TYPE_JPG:
                case TYPE_GIF:
                case TYPE_PNG:
                case TYPE_BMP:
                    type = "1";
                    break;
                case TYPE_MP3:
                case TYPE_WAV:
                case TYPE_M4A:
                    type = "2";
                    break;
                case TYPE_MP4:
                    type = "3";
                    break;
                default:
                    break;
            }
            return type;
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    4. 使用Swagger测试

    在这里插入图片描述
    可以看到已经上传至对象存储桶了
    在这里插入图片描述如何下载呢?
    将返回的URL在浏览器网址输入栏输入就行

    这篇文章就先介绍这么多,后面会更新拓展!如果你觉得这篇文章对你有帮助的话,请点赞和收藏哦!如果能点拨小小的关注就更好哦!
    在这里插入图片描述

  • 相关阅读:
    Redis 分布式锁
    nvm获取可用列表报错Could not retrieve https://nodejs.org/dist/index.json
    Spring之bean的生命周期
    C++ 观察者模式
    首周聚焦百度智能云千帆大模型平台使用,《大模型应用实践》实训营11月16日开讲!
    餐厅点餐系统的设计
    Java项目实战-查询用户列表接口服务搭建
    园区写字楼都在用的物业管理系统
    Java 进阶集合和数据结构
    为保证软件开发质量,如何提高检查效率?
  • 原文地址:https://blog.csdn.net/Baridhu/article/details/128140107