• springboot整合OSS实现文件上传


    OSS

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

    OSS中得到相关概念

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

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

    1566008566130

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

    整合OSS实现文件上传

    一、添加依赖

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

    二、修改配置文件

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

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

    三、添加OSS的相关java配置

    package top.xtslife.practice.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;
    
    /**
     * 用于配置OSS的连接客户端OSSClient。
     * @Author 小涛
     * @Create 2019-08-16  18:04
     */
    @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 top.xtslife.practice.component;
    
    import io.swagger.annotations.ApiModelProperty;
    import lombok.Data;
    
    /**
     * 获取OSS上传文件授权返回结果
     * @Author 小涛
     * @Create 2019-08-16  19:05
     */
    @Data
    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;
    }
    

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

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

    package top.xtslife.practice.component;
    
    import io.swagger.annotations.ApiModelProperty;
    import lombok.Data;
    
    /**
     * oss上传成功后的回调参数
     * @Author 小涛
     * @Create 2019-08-16  19:34
     */
    @Data
    public class OssCallbackParam {
        @ApiModelProperty("请求的回调地址")
        private String callbackUrl;
        @ApiModelProperty("回调是传入request中的参数")
        private String callbackBody;
        @ApiModelProperty("回调时传入参数格式,比如表单提交形式")
        private String callbackBodyType;
    }
    

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

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

    package top.xtslife.practice.component;
    
    import io.swagger.annotations.ApiModelProperty;
    import lombok.Data;
    
    /**
     * @Author 小涛
     * @Create 2019-08-16  19:54
     */
    @Data
    public class OssCallbackResult {
        @ApiModelProperty("文件名称")
        private String filename;
        @ApiModelProperty("文件大小")
        private String size;
        @ApiModelProperty("文件的mimeType")
        private String  mimeType;
        @ApiModelProperty("图片文件的宽")
        private String width;
        @ApiModelProperty("图片文件的高")
        private String height;
    }
    

    七、添加OSS业务接口OssService

    package top.xtslife.practice.Service;
    
    import top.xtslife.practice.component.OssCallbackResult;
    import top.xtslife.practice.component.OssPolicyResult;
    
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * oss上传管理Service
     * @Author 小涛
     * @Create 2019-08-16  20:22
     */
    public interface OssService {
        /**
         * oss 上传生成策略
         * @return
         */
        OssPolicyResult policy();
    
        /**
         * oss上传成功回调
         * @param request
         * @return
         */
        OssCallbackResult callback(HttpServletRequest request);
    }
    
    

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

    package top.xtslife.practice.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 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 top.xtslife.practice.Service.OssService;
    import top.xtslife.practice.component.OssCallbackParam;
    import top.xtslife.practice.component.OssCallbackResult;
    import top.xtslife.practice.component.OssPolicyResult;
    
    import javax.servlet.http.HttpServletRequest;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * oss上传管理Service实现类
     * @Author 小涛
     * @Create 2019-08-16  20:28
     */
    @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;
    
        /**
         * 签名生成
         * @return
         */
        @Override
        public OssPolicyResult policy() {
            OssPolicyResult ossPolicyResult = 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);
            // 文件大小
            int maxSize = ALIYUN_OSS_MAX_SIZE * 1024 * 1024;
            // 回调
            OssCallbackParam ossCallbackParam = new OssCallbackParam();
            ossCallbackParam.setCallbackUrl(ALIYUN_OSS_CALLBACK);
            ossCallbackParam.setCallbackBody("filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}");
            ossCallbackParam.setCallbackBodyType("application/x-www-form-urlencoded");
            // 提交节点
            String action = "http://"+ ALIYUN_OSS_ENDPOINT;
            try {
                PolicyConditions policyConditions = new PolicyConditions();
                policyConditions.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE,0,maxSize);
                policyConditions.addConditionItem(MatchMode.StartWith,PolicyConditions.COND_KEY,dir);
                String  postPolicy = ossClient.generatePostPolicy(expiration,policyConditions);
                byte[] binaryData = new byte[0];
                binaryData = postPolicy.getBytes("utf-8");
                String policy = BinaryUtil.toBase64String(binaryData);
                String signature = ossClient.calculatePostSignature(postPolicy);
                String callbackData = BinaryUtil.toBase64String(JSONUtil.parse(ossCallbackParam).toString().getBytes("utf-8"));
                // 返回结果
                ossPolicyResult.setAccessKeyId(ossClient.getCredentialsProvider().getCredentials().getAccessKeyId());
                ossPolicyResult.setPolicy(policy);
                ossPolicyResult.setSignature(signature);
                ossPolicyResult.setDir(dir);
                ossPolicyResult.setCallback(callbackData);
                ossPolicyResult.setHost(action);
            } catch (Exception e) {
               LOGGER.error("签名生成失败",e);
            }
            return ossPolicyResult;
        }
    
        @Override
        public OssCallbackResult callback(HttpServletRequest request) {
            OssCallbackResult ossCallbackResult = new OssCallbackResult();
            String filename = request.getParameter("filename");
            filename ="http://".concat(ALIYUN_OSS_BUCKET_NAME).concat(".").concat(ALIYUN_OSS_ENDPOINT).concat("/").concat(filename);
            ossCallbackResult.setFilename(filename);
            ossCallbackResult.setSize(request.getParameter("size"));
            ossCallbackResult.setMimeType(request.getParameter("mimeType"));
            ossCallbackResult.setWidth(request.getParameter("width"));
            ossCallbackResult.setHeight(request.getParameter("height"));
            return ossCallbackResult;
        }
    }
    
    

    九、添加OssController定义接口

    package top.xtslife.practice.controller;
    
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import top.xtslife.practice.Service.OssService;
    import top.xtslife.practice.common.CommonResult;
    import top.xtslife.practice.component.OssCallbackResult;
    import top.xtslife.practice.component.OssPolicyResult;
    
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * @Author 小涛
     * @Create 2019-08-16  21:46
     */
    @RestController
    @Api(tags = "OssController",description = "Oss管理")
    @RequestMapping("/aliyun/oss")
    public class OssController {
        @Autowired
        private OssService ossServiceImpl;
        @ApiOperation("oss上传签名生成")
        @GetMapping("/policy")
        public CommonResult<OssPolicyResult> policy(){
            OssPolicyResult ossPolicyResult = ossServiceImpl.policy();
            return CommonResult.success(ossPolicyResult);
        }
    
        @ApiOperation("oss上传成功回调")
        @PostMapping("callback")
        public CommonResult<OssCallbackResult> callback(HttpServletRequest request){
            OssCallbackResult ossCallbackResult = ossServiceImpl.callback(request);
            return CommonResult.success(ossCallbackResult);
        }
    }
    
    


    作者:关小涛
    学习和分享是博客最大的乐趣,欢迎大家取之所需。
    努力是自己努力的原因,每周天写博客总结工作中的新技能和出现的问题
  • 相关阅读:
    输出由“*”组成的菱形
    一个简单的计算器(c++)
    输入学号,显示对应的姓名(c++)
    使用 Puppet 在 Windows Azure 中配备 Linux 和 Windows 环境
    微软开放技术发布针对 Mac 和 Linux 的更新版 Azure Node.JS SDK 和命令行工具
    微软开放技术开发了适用于 Windows Azure 移动服务的开源 Android SDK
    微软开放技术发布开源 Jenkins 插件以将 Windows Azure Blob 服务用的开作存储库
    VM Depot 登陆中国!
    VM Depot 喜迎中国本土开源镜像!
    VM Depot 助您使用本地开源软件架设开发 Web 站点
  • 原文地址:https://www.cnblogs.com/XtsLife/p/11367722.html
Copyright © 2020-2023  润新知