SpringBoot对接阿里云OSS上传文件以及回调(有坑)

这篇具有很好参考价值的文章主要介绍了SpringBoot对接阿里云OSS上传文件以及回调(有坑)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

今天在对接阿里云OSS对象存储, 把这过程记录下来

链接

阿里云的内容很多,文档是真的难找又难懂
本文主要是用的PostObject API 加上 Callback参数
PostObject -> https://help.aliyun.com/document_detail/31988.html?spm=a2c4g.31989.0.0
Callback -> https://help.aliyun.com/document_detail/31989.html?spm=a2c4g.31988.0.0

对接过程

  1. 前端向后端发送请求获取签名
  2. 后端与OSS服务器交互,返回前端签名
  3. 前端拿到签名,直接上传到OSS服务器
  4. 上传成功,OSS回调应用服务器,应用服务器给前端返回上传的信息

相比应用服务器直接上传到OSS,大大减少了带宽和应用服务器的压力,缺点就是相对麻烦一点

1. pom.xml

我们用的是SpringBoot,我们导入aliyun-oss-spring-boot-starter包,因为我这个是 SpringCloud项目父项目管理了SpringCloud 和 SpringCloud Alibaba 、SpringBoot版本的,所以一开始我是没有写版本号的,结果一直爆红,导不进来,然后仔细一看,原来这是aliyun-oss-spring-boot-starter,注意这个boot-starter,我还以为是cloud系列的,然而哈哈,然后导入aliyun-spring-boot-dependencies,我在仓库里面去找版本号,然而它也只有这一个1.0.0版本

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>

	<!-- 阿里云OSS -->
	<dependency>
		<groupId>com.alibaba.cloud</groupId>
		<artifactId>aliyun-oss-spring-boot-starter</artifactId>
	</dependency>
</dependencies>
<dependencyManagement>
	<dependency>
		<groupId>com.alibaba.cloud</groupId>
		<artifactId>aliyun-spring-boot-dependencies</artifactId>
		<version>1.0.0</version>
		<type>pom</type>
		<scope>import</scope>
      </dependency>
</dependencyManagement>

2. application.yml

alibaba:
  cloud:
    # 阿里控制台OSS子账户的信息 
    access-key: LTAI5tDZ51bANyHxYpwZzvpi
    secret-key: zPxHPuaZMTPzTPy0WF88vI99HHLOzO
    oss:
      # 深圳endpoint
      endpoint: oss-cn-shenzhen.aliyuncs.com
      # 认证过期 单位秒
      expireTime: 1200
      # 储存空间名字
      bucket: yues-oss

3. 核心代码

package com.yues.gulimall.thirdparty.controller;

import com.aliyun.oss.OSS;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.Callback;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
public class OssController {
    @Autowired
    private OSS ossClient;
    @Value("${alibaba.cloud.oss.endpoint}")
    private String endpoint;
    @Value("${alibaba.cloud.access-key}")
    private String accessId;
    @Value("${alibaba.cloud.oss.expireTime}")
    private long expireTime;
    @Value("${alibaba.cloud.oss.bucket}")
    private String bucket;

    /**
     * 回调
     * @param request request
     * @return Map
     */
    @RequestMapping("/ossCallback")
    public Map<String,String> ossCallback(HttpServletRequest request) {
        HashMap<String, String> result = new HashMap<>();
        String filename = request.getParameter("filename");
        Map<String, String[]> parameterMap = request.getParameterMap();
        parameterMap.forEach((item,value) -> {
            System.out.println(item);
            System.out.println(Arrays.toString(value));
        });
        filename = "https://".concat(bucket).concat(".").concat(endpoint).concat("/").concat(filename);
        result.put("url", filename);
        result.put("size", request.getParameter("size"));
        result.put("mimeType", request.getParameter("mimeType"));
        return result;
    }


    /**
     * 签名
     * @return Map
     */
    @PostMapping("/getOssSecret")
    public Map<String,String> getOssSign() {
        // 填写Host地址,格式为https://bucketname.endpoint。
        String host = "https://" + bucket + "."+ endpoint;
        // OSS会在文件上传完成后,把文件上传信息发送给应用服务器。需要外网ip
        String callbackUrl = "https://23d4-1-196-175-217.ngrok-free.app/ossCallback";
        // 设置上传到OSS文件的前缀,可置空此项。置空后,文件将上传至Bucket的根目录下。
        // 将日期作为上传的文件夹目录
        String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        String dir = format+"/";
        Map<String, String> respMap = null;
        try {
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            // 过期时间
            Date expiration = new Date(expireEndTime);
            // 上传回调参数。
            Callback callback = new Callback();
            callback.setCallbackUrl(callbackUrl);
            // 设置回调请求消息头中Host的值,即您的服务器配置Host的值。需要外网ip
             callback.setCallbackHost("23d4-1-196-175-217.ngrok-free.app");
            // 设置发起回调时请求body的值。
            callback.setCallbackBody("filename=${object}&size=${size}&mimeType=${mimeType}");
            // 设置发起回调请求的Content-Type。
            callback.setCalbackBodyType(Callback.CalbackBodyType.JSON);
            // 设置发起回调请求的自定义参数,由Key和Value组成,Key必须以x:开始。
            callback.addCallbackVar("x:var1", "value1");
            callback.addCallbackVar("x:var2", "value2");
            // 序列化callback
            String callbackString = BinaryUtil.toBase64String(new ObjectMapper().writeValueAsString(callback).getBytes(StandardCharsets.UTF_8));

            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            // 添加目录权限,返回的认证信息只能在这个目录下进行操作
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            // 生成认证 添加过期时间
            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);
            // 转为Base64
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);

            respMap = new LinkedHashMap<>();
            respMap.put("OSSAccessKeyId", accessId);
            respMap.put("policy", encodedPolicy);
            respMap.put("Signature", postSignature);
            respMap.put("dir", dir);
            respMap.put("host", host);
            respMap.put("callback", callbackString);
            // 过期时间的时间戳
            respMap.put("expire", String.valueOf(expireEndTime / 1000));
        } catch (Exception e) {
            throw new RuntimeException("aliyun上传文件获取认证信息失败:" + e.getMessage());
        }
        return  respMap;
    }
}

4. postman 调用获取签名返回

{
    "OSSAccessKeyId": "LTAI5tDZ51bANyHxYpwZzvpi",
    "policy": "eyJleHBpcmF0aW9uIjoiMjAyMy0wNy0wM1QxNzoxNzo1MS44ODBaIiwiY29uZGl0aW9ucyI6W1siY29udGVudC1sZW5ndGgtcmFuZ2UiLDAsMTA0ODU3NjAwMF0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCIyMDIzLTA3LTA0LyJdXX0=",
    "Signature": "yK5oF8Cj0ncR0ceuIMtXdMW1yco=",
    "dir": "2023-07-04/",
    "host": "https://yues-oss.oss-cn-shenzhen.aliyuncs.com",
    "callback": "eyJjYWxsYmFja1VybCI6Imh0dHBzOi8vMjNkNC0xLTE5Ni0xNzUtMjE3Lm5ncm9rLWZyZWUuYXBwL29zc0NhbGxiYWNrIiwiY2FsbGJhY2tIb3N0IjoiMjNkNC0xLTE5Ni0xNzUtMjE3Lm5ncm9rLWZyZWUuYXBwIiwiY2FsbGJhY2tCb2R5IjoiZmlsZW5hbWU9JHtvYmplY3R9JnNpemU9JHtzaXplfSZtaW1lVHlwZT0ke21pbWVUeXBlfSIsImNhbGJhY2tCb2R5VHlwZSI6IkpTT04iLCJjYWxsYmFja1ZhciI6eyJ4OnZhcjIiOiJ2YWx1ZTIiLCJ4OnZhcjEiOiJ2YWx1ZTEifX0=",
    "expire": "1688404671"
}

5. 前端上传到OSS

拿到第四步的JSON后,请求JSON中的host,key = dir + 文件名.后缀,然后按照下图方式请求
SpringBoot对接阿里云OSS上传文件以及回调(有坑)
注意文章来源地址https://www.toymoban.com/news/detail-516680.html

  1. Content-Type要为multipart/form-data;
  2. file 必须在表单数据中最后一个
  3. 上传的file大小不能超过5 GB
  4. 不知道为什么 我这边postman上传的file,它的文件名字不能是中文的,不然就会返回405,这个问题调试我半天,我觉得应该是字符编码哪里要设置一下,没有具体研究下去了

到了这里,关于SpringBoot对接阿里云OSS上传文件以及回调(有坑)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot+Vue实现阿里云OSS服务器签名直传并且返回回调数据

    vue java 可参考官方文档:如何通过Java在服务端签名直传并设置上传回调_对象存储-阿里云帮助中心  

    2024年02月13日
    浏览(30)
  • SpringBoot3 + uniapp 对接 阿里云0SS 实现上传图片视频到 0SS 以及 0SS 里删除图片视频的操作(最新)

    UpLoadFile.vue deleteOssFile.js http.js FileUploadController.java AliOssUtil.java

    2024年04月14日
    浏览(32)
  • 如何使用阿里云OSS进行前端直传以及分片上传

    在使用阿里云OSS进行前端直传时,首先我们需要去阿里云官网注册自己的存储桶,然后申请相关的accessKeyId和accessKeySecret,然后新建一个桶,为这个桶命名以及选择对应的地区。 然后可以根据自己的业务,封装对应的组件,以下是根据我自己的项目,所封装的上传组件,所用

    2024年02月21日
    浏览(37)
  • 阿里云OSS文件上传

    需求分析:实现文件上传与下载 ,与SprinCloud Alibaba整合 步骤一:注册帐号 阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台  第二步:创建Bucket  第三步,创建Accesskey  注意:创建时候一定记得复制帐号密码,密码只在创建成功后显示一次! 第四步:安装对象存储

    2024年01月24日
    浏览(45)
  • 使用SpringBoot将图片上传至阿里云OSS

    1. 什么是OSS? 官方的解释是这样的:阿里云对象存储OSS(Object Storage Service)是一款海量、安全、低成本、高可靠的云存储服务,提供99.9999999999%(12个9)的数据持久性,99.995%的数据可用性。 官网:对象存储OSS 2. 为什么要使用OSS? 作者认为主要是方便项目上线后的文件业务的处

    2024年02月06日
    浏览(29)
  • 阿里云对象存储OSS文件上传

    阿里云oss地址: 对象存储OSS_云存储服务_企业数据管理_存储-阿里云 阿里云对象存储OSS是一款海量、安全、低成本、高可靠的云存储服务,提供12个9的数据持久性,99.995%的数据可用性和多种存储类型,适用于数据湖存储,数据迁移,企业数据管理,数据处理等多种场景,可对

    2024年02月12日
    浏览(32)
  • Golang操作阿里云OSS上传文件

    为什么要使用OSS?应用场景是什么? 最近在开发考试系统,里面需要上传课件,课件包括pdf,map等等各种类型的文件,这些文件不能像图片一样,直接上传到项目目录下面,需要单独存放,阿里云就提供了存储方式,然后OSS是其中的一种,可以用来存储一些文件。 我们需要

    2024年02月02日
    浏览(35)
  • SpringCloud整合阿里云OSS实现文件上传

    阿里云OSS官网:OSS管理控制台 (aliyun.com) 什么是对象存储OSS 阿里云对象存储OSS(Object Storage Service)是一款海量、安全、低成本、高可靠的云存储服务,可提供99.9999999999%(12个9)的数据持久性,99.995%的数据可用性。多种存储类型供选择,全面优化存储成本。 OSS具有与平台无

    2023年04月13日
    浏览(30)
  • vue+iviewUi+oss直传阿里云上传文件

    用户获取oss配置信息将文件上传到阿里云,保证了安全性和减轻服务器负担。一般文件资源很多直接上传到服务器会加重服务器负担此时可以选择上传到oss,轻量型的应用可以直接将文件资源上传到服务器就行。废话不多说,下面开始总结本人上传到oss的踩坑之旅。 1、第一

    2024年02月13日
    浏览(34)
  • node.js - 上传文件至阿里云oss

    deploy.js

    2024年02月08日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包