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

  • Post author:
  • Post category:其他




一. 对象存储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.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.14.0</version>
</dependency>




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. 把鼠标移动到自己头像位置会出悬浮框,我们选择

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);
    }
}


其功能是实现图片上传至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:

SpringContextUtils.getContext().getBean(SnowFlakeUtils.class).nextId()

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

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


补充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;
    }

}




4. 使用Swagger测试

在这里插入图片描述


可以看到已经上传至对象存储桶了


在这里插入图片描述

如何下载呢?



将返回的URL在浏览器网址输入栏输入就行


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


在这里插入图片描述



版权声明:本文为Baridhu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。