SpringBoot对接阿里云OSS上传文件以及回调(有坑)|世界快资讯
2023-07-04 06:26:57来源:博客园
(相关资料图)
前言今天在对接阿里云OSS对象存储, 把这过程记录下来
链接阿里云的内容很多,文档是真的难找又难懂本文主要是用的PostObject API 加上 Callback参数PostObject -> https://help.aliyun.com/document_detail/31988.html?spm=a2c4g.31989.0.0Callback -> https://help.aliyun.com/document_detail/31989.html?spm=a2c4g.31988.0.0
对接过程前端向后端发送请求获取签名后端与OSS服务器交互,返回前端签名前端拿到签名,直接上传到OSS服务器上传成功,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版本
org.springframework.boot spring-boot-starter-web com.alibaba.cloud aliyun-oss-spring-boot-starter com.alibaba.cloud aliyun-spring-boot-dependencies 1.0.0 pom import
2. application.ymlalibaba: 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.*;@RestControllerpublic 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 ossCallback(HttpServletRequest request) { HashMap result = new HashMap<>(); String filename = request.getParameter("filename"); Map 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 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 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 + 文件名.后缀,然后按照下图方式请求注意:
Content-Type要为multipart/form-data;file 必须在表单数据中最后一个上传的file大小不能超过5 GB不知道为什么 我这边postman上传的file,它的文件名字不能是中文的,不然就会返回405,这个问题调试我半天,我觉得应该是字符编码哪里要设置一下,没有具体研究下去了本网推荐
- SpringBoot对接阿里云OSS上传文件以及回调(有坑)|世界快资讯
- 全球新动态:女单四强对阵出炉!国乒独占三席包围伊藤美诚,德国赛后再遇丁宁
- 7月3日基金净值:博时恒泰债券A最新净值1.0587,涨0.07% 最新快讯
- 房产销售经理述职报告格式
- 环球头条:装腔作势意思(装腔作势)
- 这种难以启齿的病其实很常见!你可以不用再偷偷忍受
- 环球实时:微粒贷逾期二万会坐几年牢?逾期多少天需要全额还款?
- 过节给甲方送礼怎么说_过节送礼_天天快看
- 天天观焦点:莫里茨·施利克(关于莫里茨·施利克的简介)
- 阿科力: 无锡阿科力科技股份有限公司关于向特定对象发行股票的专项核查函回复的提示性公告
- 世界热讯:三万七定制欧洲E0级环保软装 消费者质疑维意定制虚假宣传
- 甘肃某部库室监控设施升级改造项目-变更公告 环球时讯
- 京东购物怎么退货_微信小程序京东购物怎么退货
- 洛阳偃师区检察院:宣传服务零距离 司法救助惠民生
- 三大指数继续反弹,汽车板块表现活跃!_微动态
- 今头条!相聚在鸢都 相约西海岸 第33届青岛国际啤酒节暨青岛西海岸新区“双城记”文旅推介活动走进潍坊
- 公司内部调整 王平不再担任招商沪深300增强策略ETF基金经理|焦点短讯
- HPE CEO Antonio Neri: 聚焦边缘、云和人工智能,以创新塑造美好未来
- 宣绩铁路一标段514孔双线梁全部架设完成
- 云冈特展在苏州吴文化博物馆展出|环球报道
- 认股权贷款的AB面:商业银行在顾虑些什么?
- 环球要闻:shear怎么读_shear
- 全球视点!借景抒情的作文300字郁金香_借景抒情的作文300字
- 2023 TCL全球生态合作伙伴大会亮点前瞻:即将官宣碳中和行动计划|天天快播
- 蔡依林入驻快手 独家直播开唱定档7月14日晚8点
- 天天即时看!市场观察:哪些细节展现了四季沐歌坚守本源,客户至上的理念?
- 焦点快看:《长安三万里》举行全球首映礼 唐风席卷神州大地
- 热推荐:德方纳米:6月30日获融资买入1.23亿元,占当日流入资金比例15.24%
- 全球微动态丨高效准确填报志愿,要做好这些“功课”
- 霍雨浩为什么痛恨唐三(绝世唐门讲了什么故事)