OSS实现文件上传_oss文件上传-程序员宅基地

本文主要讲解mall整合OSS实现文件上传的过程,采用的是服务端签名后前端直传的方式。

OSS

阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。OSS可用于图片、音视频、日志等海量文件的存储。各种终端设备、Web网站程序、移动应用可以直接向OSS写入或读取数据。

OSS中的相关概念

  • Endpoint:访问域名,通过该域名可以访问OSS服务的API,进行文件上传、下载等操作。
  • Bucket:存储空间,是存储对象的容器,所有存储对象都必须隶属于某个存储空间。
  • Object:对象,对象是 OSS 存储数据的基本单元,也被称为 OSS 的文件。
  • AccessKey:访问密钥,指的是访问身份验证中用到的 AccessKeyId 和 AccessKeySecret。

OSS的相关设置

开通OSS服务
  • 登录阿里云官网;
  • 将鼠标移至产品标签页,单击对象存储 OSS,打开OSS 产品详情页面;
  • 在OSS产品详情页,单击立即开通。
创建存储空间
  1. 点击网页右上角控制台按钮进入控制台
    在这里插入图片描述
  2. 选择我的云产品中的对象存储OSS
    在这里插入图片描述
  3. 点击左侧存储空间的加号新建存储空间
    在这里插入图片描述
  4. 新建存储空间并设置读写权限为公共读
    在这里插入图片描述
跨域资源共享(CORS)的设置

由于浏览器处于安全考虑,不允许跨域资源访问,所以我们要设置OSS的跨域资源共享。
5. 选择一个存储空间,打开其基础设置
在这里插入图片描述
6. 点击跨越设置的设置按钮
在这里插入图片描述
7. 点击创建规则
在这里插入图片描述
8. 进行跨域规则设置
在这里插入图片描述

服务端签名后前端直传的相关说明

流程示例图

在这里插入图片描述

流程介绍
  1. Web前端请求应用服务器,获取上传所需参数(如OSS的accessKeyId、policy、callback等参数)
  2. 应用服务器返回相关参数
  3. Web前端直接向OSS服务发起上传文件请求
  4. 等上传完成后OSS服务会回调应用服务器的回调接口
  5. 应用服务器返回响应给OSS服务
  6. OSS服务将应用服务器回调接口的内容返回给Web前端

整合OSS实现文件上传

在pom.xml中添加相关依赖


	<!-- OSS SDK 相关依赖 -->
	<dependency>
	    <groupId>com.aliyun.oss</groupId>
	    <artifactId>aliyun-sdk-oss</artifactId>
	    <version>2.5.0</version>
	</dependency>
	

修改SpringBoot配置文件

修改application.yml文件,添加OSS相关配置。

注意:endpoint、accessKeyId、accessKeySecret、bucketName、callback、prefix都要改为你自己帐号OSS相关的,callback需要是公网可以访问的地址。


	# OSS相关配置信息
	aliyun:
	  oss:
	    endpoint: oss-cn-shenzhen.aliyuncs.com # oss对外服务的访问域名
	    accessKeyId: test # 访问身份验证中用到用户标识
	    accessKeySecret: test # 用户用于加密签名字符串和oss用来验证签名字符串的密钥
	    bucketName: macro-oss # oss的存储空间
	    policy:
	      expire: 300 # 签名有效期(S)
	    maxSize: 10 # 上传文件大小(M)
	    callback: http://localhost:8080/aliyun/oss/callback # 文件上传成功后的回调地址
	    dir:
	      prefix: mall/images/ # 上传文件夹路径前缀
	      

添加OSS的相关Java配置

用于配置OSS的连接客户端OSSClient。


	package com.macro.mall.tiny.config;
	
	import com.aliyun.oss.OSSClient;
	import org.springframework.beans.factory.annotation.Value;
	import org.springframework.context.annotation.Bean;
	import org.springframework.context.annotation.Configuration;
	
	/**
	 * Created by macro on 2018/5/17.
	 */
	@Configuration
	public class OssConfig {
    
	    @Value("${aliyun.oss.endpoint}")
	    private String ALIYUN_OSS_ENDPOINT;
	    @Value("${aliyun.oss.accessKeyId}")
	    private String ALIYUN_OSS_ACCESSKEYID;
	    @Value("${aliyun.oss.accessKeySecret}")
	    private String ALIYUN_OSS_ACCESSKEYSECRET;
	    @Bean
	    public OSSClient ossClient(){
    
	        return new OSSClient(ALIYUN_OSS_ENDPOINT,ALIYUN_OSS_ACCESSKEYID,ALIYUN_OSS_ACCESSKEYSECRET);
	    }
	}
	

添加OSS上传策略封装对象OssPolicyResult

前端直接上传文件时所需参数,从后端返回过来。


	package com.macro.mall.tiny.dto;
	
	import io.swagger.annotations.ApiModelProperty;
	
	/**
	 * 获取OSS上传文件授权返回结果
	 * Created by macro on 2018/5/17.
	 */
	public class OssPolicyResult {
    
	    @ApiModelProperty("访问身份验证中用到用户标识")
	    private String accessKeyId;
	    @ApiModelProperty("用户表单上传的策略,经过base64编码过的字符串")
	    private String policy;
	    @ApiModelProperty("对policy签名后的字符串")
	    private String signature;
	    @ApiModelProperty("上传文件夹路径前缀")
	    private String dir;
	    @ApiModelProperty("oss对外服务的访问域名")
	    private String host;
	    @ApiModelProperty("上传成功后的回调设置")
	    private String callback;
	
	    //省略了所有getter,setter方法
	}
	

添加OSS上传成功后的回调参数对象OssCallbackParam

当OSS上传成功后,会根据该配置参数来回调对应接口。


	package com.macro.mall.tiny.dto;
	
	import io.swagger.annotations.ApiModelProperty;
	
	/**
	 * oss上传成功后的回调参数
	 * Created by macro on 2018/5/17.
	 */
	public class OssCallbackParam {
    
	    @ApiModelProperty("请求的回调地址")
	    private String callbackUrl;
	    @ApiModelProperty("回调是传入request中的参数")
	    private String callbackBody;
	    @ApiModelProperty("回调时传入参数的格式,比如表单提交形式")
	    private String callbackBodyType;
	
	    //省略了所有getter,setter方法
	}
	

OSS上传成功后的回调结果对象OssCallbackResult

回调接口中返回的数据对象,封装了上传文件的信息。


	package com.macro.mall.tiny.dto;
	
	import io.swagger.annotations.ApiModelProperty;
	
	/**
	 * oss上传文件的回调结果
	 * Created by macro on 2018/5/17.
	 */
	public class OssCallbackResult {
    
	    @ApiModelProperty("文件名称")
	    private String filename;
	    @ApiModelProperty("文件大小")
	    private String size;
	    @ApiModelProperty("文件的mimeType")
	    private String mimeType;
	    @ApiModelProperty("图片文件的宽")
	    private String width;
	    @ApiModelProperty("图片文件的高")
	    private String height;
	
	    //省略了所有getter,setter方法
	}
	

添加OSS业务接口OssService


	package com.macro.mall.tiny.service;
	
	import com.macro.mall.tiny.dto.OssCallbackResult;
	import com.macro.mall.tiny.dto.OssPolicyResult;
	
	import javax.servlet.http.HttpServletRequest;
	
	/**
	 * oss上传管理Service
	 * Created by macro on 2018/5/17.
	 */
	public interface OssService {
    
	    /**
	     * oss上传策略生成
	     */
	    OssPolicyResult policy();
	
	    /**
	     * oss上传成功回调
	     */
	    OssCallbackResult callback(HttpServletRequest request);
	}
	

添加OSS业务接口OssService的实现类OssServiceImpl


	package com.macro.mall.tiny.service.impl;
	
	import cn.hutool.json.JSONUtil;
	import com.aliyun.oss.OSSClient;
	import com.aliyun.oss.common.utils.BinaryUtil;
	import com.aliyun.oss.model.MatchMode;
	import com.aliyun.oss.model.PolicyConditions;
	import com.macro.mall.tiny.dto.OssCallbackParam;
	import com.macro.mall.tiny.dto.OssCallbackResult;
	import com.macro.mall.tiny.dto.OssPolicyResult;
	import com.macro.mall.tiny.service.OssService;
	import org.slf4j.Logger;
	import org.slf4j.LoggerFactory;
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.beans.factory.annotation.Value;
	import org.springframework.stereotype.Service;
	
	import javax.servlet.http.HttpServletRequest;
	import java.text.SimpleDateFormat;
	import java.util.Date;
	
	/**
	 * oss上传管理Service实现类
	 * Created by macro on 2018/5/17.
	 */
	@Service
	public class OssServiceImpl implements OssService {
    
	
	    private static final Logger LOGGER = LoggerFactory.getLogger(OssServiceImpl.class);
	    @Value("${aliyun.oss.policy.expire}")
	    private int ALIYUN_OSS_EXPIRE;
	    @Value("${aliyun.oss.maxSize}")
	    private int ALIYUN_OSS_MAX_SIZE;
	    @Value("${aliyun.oss.callback}")
	    private String ALIYUN_OSS_CALLBACK;
	    @Value("${aliyun.oss.bucketName}")
	    private String ALIYUN_OSS_BUCKET_NAME;
	    @Value("${aliyun.oss.endpoint}")
	    private String ALIYUN_OSS_ENDPOINT;
	    @Value("${aliyun.oss.dir.prefix}")
	    private String ALIYUN_OSS_DIR_PREFIX;
	
	    @Autowired
	    private OSSClient ossClient;
	
	    /**
	     * 签名生成
	     */
	    @Override
	    public OssPolicyResult policy() {
    
	        OssPolicyResult result = new OssPolicyResult();
	        // 存储目录
	        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
	        String dir = ALIYUN_OSS_DIR_PREFIX+sdf.format(new Date());
	        // 签名有效期
	        long expireEndTime = System.currentTimeMillis() + ALIYUN_OSS_EXPIRE * 1000;
	        Date expiration = new Date(expireEndTime);
	        // 文件大小
	        long maxSize = ALIYUN_OSS_MAX_SIZE * 1024 * 1024;
	        // 回调
	        OssCallbackParam callback = new OssCallbackParam();
	        callback.setCallbackUrl(ALIYUN_OSS_CALLBACK);
	        callback.setCallbackBody("filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}");
	        callback.setCallbackBodyType("application/x-www-form-urlencoded");
	        // 提交节点
	        String action = "http://" + ALIYUN_OSS_BUCKET_NAME + "." + ALIYUN_OSS_ENDPOINT;
	        try {
    
	            PolicyConditions policyConds = new PolicyConditions();
	            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, maxSize);
	            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
	            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
	            byte[] binaryData = postPolicy.getBytes("utf-8");
	            String policy = BinaryUtil.toBase64String(binaryData);
	            String signature = ossClient.calculatePostSignature(postPolicy);
	            String callbackData = BinaryUtil.toBase64String(JSONUtil.parse(callback).toString().getBytes("utf-8"));
	            // 返回结果
	            result.setAccessKeyId(ossClient.getCredentialsProvider().getCredentials().getAccessKeyId());
	            result.setPolicy(policy);
	            result.setSignature(signature);
	            result.setDir(dir);
	            result.setCallback(callbackData);
	            result.setHost(action);
	        } catch (Exception e) {
    
	            LOGGER.error("签名生成失败", e);
	        }
	        return result;
	    }
	
	    @Override
	    public OssCallbackResult callback(HttpServletRequest request) {
    
	        OssCallbackResult result= new OssCallbackResult();
	        String filename = request.getParameter("filename");
	        filename = "http://".concat(ALIYUN_OSS_BUCKET_NAME).concat(".").concat(ALIYUN_OSS_ENDPOINT).concat("/").concat(filename);
	        result.setFilename(filename);
	        result.setSize(request.getParameter("size"));
	        result.setMimeType(request.getParameter("mimeType"));
	        result.setWidth(request.getParameter("width"));
	        result.setHeight(request.getParameter("height"));
	        return result;
	    }
	
	}
	

添加OssController定义接口


	package com.macro.mall.tiny.controller;
	
	
	import com.macro.mall.tiny.common.api.CommonResult;
	import com.macro.mall.tiny.dto.OssCallbackResult;
	import com.macro.mall.tiny.dto.OssPolicyResult;
	import com.macro.mall.tiny.service.impl.OssServiceImpl;
	import io.swagger.annotations.Api;
	import io.swagger.annotations.ApiOperation;
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.stereotype.Controller;
	import org.springframework.web.bind.annotation.RequestMapping;
	import org.springframework.web.bind.annotation.RequestMethod;
	import org.springframework.web.bind.annotation.ResponseBody;
	
	import javax.servlet.http.HttpServletRequest;
	
	/**
	 * Oss相关操作接口
	 * Created by macro on 2018/4/26.
	 */
	@Controller
	@Api(tags = "OssController", description = "Oss管理")
	@RequestMapping("/aliyun/oss")
	public class OssController {
    
	    @Autowired
	    private OssServiceImpl ossService;
	
	    @ApiOperation(value = "oss上传签名生成")
	    @RequestMapping(value = "/policy", method = RequestMethod.GET)
	    @ResponseBody
	    public CommonResult<OssPolicyResult> policy() {
    
	        OssPolicyResult result = ossService.policy();
	        return CommonResult.success(result);
	    }
	
	    @ApiOperation(value = "oss上传成功回调")
	    @RequestMapping(value = "callback", method = RequestMethod.POST)
	    @ResponseBody
	    public CommonResult<OssCallbackResult> callback(HttpServletRequest request) {
    
	        OssCallbackResult ossCallbackResult = ossService.callback(request);
	        return CommonResult.success(ossCallbackResult);
	    }
	
	}

进行接口测试

测试获取上传策略的接口

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

启动mall-admin-web前端项目来测试上传接口

  • 如何启动前端项目,具体参考该项目的readme文档:https://github.com/macrozheng/mall-admin-web
  • 点击添加商品品牌的上传按钮进行测试
    在这里插入图片描述
  • 会调用两次请求,第一次访问本地接口获取上传的策略
    在这里插入图片描述
    在这里插入图片描述
  • 第二次调用oss服务 的接口进行文件上传
    在这里插入图片描述
    在这里插入图片描述
  • 可以看到上面接口调用并没有传入回调参数callback,所以接口返回了204 no
    content,这次我们传入回调参数callback试试,可以发现oss服务回调了我们自己定义的回调接口,并返回了相应结果。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_45879810/article/details/117108821

智能推荐

hive使用适用场景_大数据入门:Hive应用场景-程序员宅基地

文章浏览阅读5.8k次。在大数据的发展当中,大数据技术生态的组件,也在不断地拓展开来,而其中的Hive组件,作为Hadoop的数据仓库工具,可以实现对Hadoop集群当中的大规模数据进行相应的数据处理。今天我们的大数据入门分享,就主要来讲讲,Hive应用场景。关于Hive,首先需要明确的一点就是,Hive并非数据库,Hive所提供的数据存储、查询和分析功能,本质上来说,并非传统数据库所提供的存储、查询、分析功能。Hive..._hive应用场景

zblog采集-织梦全自动采集插件-织梦免费采集插件_zblog 网页采集插件-程序员宅基地

文章浏览阅读496次。Zblog是由Zblog开发团队开发的一款小巧而强大的基于Asp和PHP平台的开源程序,但是插件市场上的Zblog采集插件,没有一款能打的,要么就是没有SEO文章内容处理,要么就是功能单一。很少有适合SEO站长的Zblog采集。人们都知道Zblog采集接口都是对Zblog采集不熟悉的人做的,很多人采取模拟登陆的方法进行发布文章,也有很多人直接操作数据库发布文章,然而这些都或多或少的产生各种问题,发布速度慢、文章内容未经严格过滤,导致安全性问题、不能发Tag、不能自动创建分类等。但是使用Zblog采._zblog 网页采集插件

Flink学习四:提交Flink运行job_flink定时运行job-程序员宅基地

文章浏览阅读2.4k次,点赞2次,收藏2次。restUI页面提交1.1 添加上传jar包1.2 提交任务job1.3 查看提交的任务2. 命令行提交./flink-1.9.3/bin/flink run -c com.qu.wc.StreamWordCount -p 2 FlinkTutorial-1.0-SNAPSHOT.jar3. 命令行查看正在运行的job./flink-1.9.3/bin/flink list4. 命令行查看所有job./flink-1.9.3/bin/flink list --all._flink定时运行job

STM32-LED闪烁项目总结_嵌入式stm32闪烁led实验总结-程序员宅基地

文章浏览阅读1k次,点赞2次,收藏6次。这个项目是基于STM32的LED闪烁项目,主要目的是让学习者熟悉STM32的基本操作和编程方法。在这个项目中,我们将使用STM32作为控制器,通过对GPIO口的控制实现LED灯的闪烁。这个STM32 LED闪烁的项目是一个非常简单的入门项目,但它可以帮助学习者熟悉STM32的编程方法和GPIO口的使用。在这个项目中,我们通过对GPIO口的控制实现了LED灯的闪烁。LED闪烁是STM32入门课程的基础操作之一,它旨在教学生如何使用STM32开发板控制LED灯的闪烁。_嵌入式stm32闪烁led实验总结

Debezium安装部署和将服务托管到systemctl-程序员宅基地

文章浏览阅读63次。本文介绍了安装和部署Debezium的详细步骤,并演示了如何将Debezium服务托管到systemctl以进行方便的管理。本文将详细介绍如何安装和部署Debezium,并将其服务托管到systemctl。解压缩后,将得到一个名为"debezium"的目录,其中包含Debezium的二进制文件和其他必要的资源。注意替换"ExecStart"中的"/path/to/debezium"为实际的Debezium目录路径。接下来,需要下载Debezium的压缩包,并将其解压到所需的目录。

Android 控制屏幕唤醒常亮或熄灭_android实现拿起手机亮屏-程序员宅基地

文章浏览阅读4.4k次。需求:在诗词曲文项目中,诗词整篇朗读的时候,文章没有读完会因为屏幕熄灭停止朗读。要求:在文章没有朗读完毕之前屏幕常亮,读完以后屏幕常亮关闭;1.权限配置:设置电源管理的权限。

随便推点

目标检测简介-程序员宅基地

文章浏览阅读2.3k次。目标检测简介、评估标准、经典算法_目标检测

记SQL server安装后无法连接127.0.0.1解决方法_sqlserver 127 0 01 无法连接-程序员宅基地

文章浏览阅读6.3k次,点赞4次,收藏9次。实训时需要安装SQL server2008 R所以我上网上找了一个.exe 的安装包链接:https://pan.baidu.com/s/1_FkhB8XJy3Js_rFADhdtmA提取码:ztki注:解压后1.04G安装时Microsoft需下载.NET,更新安装后会自动安装如下:点击第一个傻瓜式安装,唯一注意的是在修改路径的时候如下不可修改:到安装实例的时候就可以修改啦数据..._sqlserver 127 0 01 无法连接

js 获取对象的所有key值,用来遍历_js 遍历对象的key-程序员宅基地

文章浏览阅读7.4k次。1. Object.keys(item); 获取到了key之后就可以遍历的时候直接使用这个进行遍历所有的key跟valuevar infoItem={ name:'xiaowu', age:'18',}//的出来的keys就是[name,age]var keys=Object.keys(infoItem);2. 通常用于以下实力中 <div *ngFor="let item of keys"> <div>{{item}}.._js 遍历对象的key

粒子群算法(PSO)求解路径规划_粒子群算法路径规划-程序员宅基地

文章浏览阅读2.2w次,点赞51次,收藏310次。粒子群算法求解路径规划路径规划问题描述    给定环境信息,如果该环境内有障碍物,寻求起始点到目标点的最短路径, 并且路径不能与障碍物相交,如图 1.1.1 所示。1.2 粒子群算法求解1.2.1 求解思路    粒子群优化算法(PSO),粒子群中的每一个粒子都代表一个问题的可能解, 通过粒子个体的简单行为,群体内的信息交互实现问题求解的智能性。    在路径规划中,我们将每一条路径规划为一个粒子,每个粒子群群有 n 个粒 子,即有 n 条路径,同时,每个粒子又有 m 个染色体,即中间过渡点的_粒子群算法路径规划

量化评价:稳健的业绩评价指标_rar 海龟-程序员宅基地

文章浏览阅读353次。所谓稳健的评估指标,是指在评估的过程中数据的轻微变化并不会显著的影响一个统计指标。而不稳健的评估指标则相反,在对交易系统进行回测时,参数值的轻微变化会带来不稳健指标的大幅变化。对于不稳健的评估指标,任何对数据有影响的因素都会对测试结果产生过大的影响,这很容易导致数据过拟合。_rar 海龟

IAP在ARM Cortex-M3微控制器实现原理_value line devices connectivity line devices-程序员宅基地

文章浏览阅读607次,点赞2次,收藏7次。–基于STM32F103ZET6的UART通讯实现一、什么是IAP,为什么要IAPIAP即为In Application Programming(在应用中编程),一般情况下,以STM32F10x系列芯片为主控制器的设备在出厂时就已经使用J-Link仿真器将应用代码烧录了,如果在设备使用过程中需要进行应用代码的更换、升级等操作的话,则可能需要将设备返回原厂并拆解出来再使用J-Link重新烧录代码,这就增加了很多不必要的麻烦。站在用户的角度来说,就是能让用户自己来更换设备里边的代码程序而厂家这边只需要提供给_value line devices connectivity line devices