springboot 文件上传 阿里云OSS

一、介绍

文件上传,是指将本地图片、视频、音频等文件上传到服务器上,可以供其他用户浏览或下载的过程。文件上传在项目中应用非常广泛,我们经常发抖音、发朋友圈都用到了文件上传功能。

实现文件上传服务,需要有存储的支持,那么我们的解决方案将以下几种:

  1. 直接将图片保存到服务的硬盘(springmvc中的文件上传)
    1. 优点:开发便捷,成本低
    2. 缺点:扩容困难
  2. 使用分布式文件系统进行存储
    1. 优点:容易实现扩容
    2. 缺点:开发复杂度稍大(有成熟的产品可以使用,比如:FastDFS,MinIO)
  3. 使用第三方的存储服务(例如OSS)
    1. 优点:开发简单,拥有强大功能,免维护
    2. 缺点:付费

在章节介绍阿里云的OSS服务进行文件存储。

二、阿里云 对象存储OSS

这里的阿里云注册购买相关可以学习黑马:

https://www.bilibili.com/video/BV1m84y1w7Tb?p=149&spm_id_from=pageDriver&vd_source=4753af08dc12ba29bcc0b79e921e5dd4

三、代码开发

1、接口文档

请求参数

在这里插入图片描述

返回数据

在这里插入图片描述

可以看到,后端是需要给前端返回一个文件的上传路径的。因为前端可能就是通过这个路径,来将图片展示给用户。

2、yml 配置阿里云信息

开发阶段 使用 dev 开发环境
在 application.yml 中配置阿里云oss

spring:
  profiles:
    active: dev    #设置环境
sky:
  alioss:
    endpoint: ${sky.alioss.endpoint}
    access-key-id: ${sky.alioss.access-key-id}
    access-key-secret: ${sky.alioss.access-key-secret}
    bucket-name: ${sky.alioss.bucket-name}

在 application-dev.yml 中配置上阿里云oss的信息

sky:
  alioss:
    endpoint: oss-cn-hangzhou.aliyuncs.com
    access-key-id: 你的accessskeyid
    access-key-secret: 你的accessskeysecret
    bucket-name: sky-take-out

3、读取OSS配置

通过AliOssProperties 来读取配置文件中的数据,连接到阿里云。

@Component
@ConfigurationProperties(prefix = "sky.alioss")
@Data
public class AliOssProperties {

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;

}

AliOssProperties
这是一个配置属性类,作用在于:将我们这个配置文件中信息封装成Java对象。
@ConfigurationProperties(prefix = “sky.alioss”)
prefix = "sky.alioss"代表 扫描 yml中前缀为 sky.alioss 的信息。

4、创建工具类AliOssUtil

实现文件上传阿里云OSS

@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;

    /**
     * 文件上传
     *
     * @param bytes
     * @param objectName
     * @return
     */
    public String upload(byte[] bytes, String objectName) {

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        //文件访问路径规则 https://BucketName.Endpoint/ObjectName
        StringBuilder stringBuilder = new StringBuilder("https://");
        stringBuilder
                .append(bucketName)
                .append(".")
                .append(endpoint)
                .append("/")
                .append(objectName);

        log.info("文件上传到:{}", stringBuilder.toString());

        return stringBuilder.toString();
    }
}

5、再创建OssConfiguration配置类

用于创建第四步的AliOssUtil对象

为什么需要这个配置类呢?
设置成配置类,在我们后端服务启动时,配置类也会生效,在我们需要的时候就可以直接使用配置类中的方法。

/**
 * 配置类,用于创建AliOssUtil对象
 */
@Configuration
@Slf4j
public class OssConfiguration {

    @Bean
    @ConditionalOnMissingBean //保证spring容器中,只有这一个util对象。多了浪费;
    public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties){
        log.info("开始创建阿里云文件上传工具类对象:{}",aliOssProperties);
        return new AliOssUtil(aliOssProperties.getEndpoint(),
                aliOssProperties.getAccessKeyId(),
                aliOssProperties.getAccessKeySecret(),
                aliOssProperties.getBucketName());
    }
}

6、Controller

/**
 * 通用接口
 */
@RestController
@RequestMapping("/admin/common")
@Api(tags = "通用接口")
@Slf4j
public class CommonController {

    @Autowired
    private AliOssUtil aliOssUtil;

    /**
     * 文件上传
     * @param file
     * @return
     */
    @PostMapping("/upload")
    @ApiOperation("文件上传")
    public Result<String> upload(MultipartFile file){
        log.info("文件上传:{}",file);

        try {
            //原始文件名
            String originalFilename = file.getOriginalFilename();
            //截取原始文件名的后缀   dfdfdf.png
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            //构造新文件名称( 防止存在阿里云的文件名重复,会被新的覆盖)
            String objectName = UUID.randomUUID().toString() + extension;

            //文件的请求路径
            String filePath = aliOssUtil.upload(file.getBytes(), objectName);
            return Result.success(filePath);
        } catch (IOException e) {
            log.error("文件上传失败:{}", e);
        }

        return Result.error(MessageConstant.UPLOAD_FAILED);
    }
}

测试

前端上传文件
配置类在springboot启动后生效。
在这里插入图片描述
上传成功
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值