文章目录

  • 使用手册
    • maven依赖及环境配置
    • 定义配置bean及OSS工具类
    • 定义UploadController和DownloadController
      • 下载接口优化为返回重定向oss路径
  • 遇到的问题
    • The bucket you visit is not belong to you
    • 从OSS获取临时url是http协议的

    为解决服务端IO压力,将文件服务转移至阿里云OSS,先丢一个 阿里云OSS官网链接。 上传及下载流程为:将文件上传至OSS,并拿到文件对应的key。根据获取key,再从OSS获取文件临时URL(安全性考虑,加上了url有效期)。

    突然想起好久没写博客了,正好上来记录一二~ 关于代码中的oss配置,想着写成一个统一配置bean,这样就不用在每一个使用的地方都进行设值,但由于本人太懒了等后期再倒腾吧~

使用手册

Step1:加入maven依赖及配置文件中配置秘钥等
Step2:定义配置bean与OSS工具类
Step3:定义UploadController和DownloadController

maven依赖及环境配置

  1. 在pom.xml中加入依赖:
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alicloud-oss</artifactId>
</dependency>
  1. 在bootstraps.yml(或application.yml等)中配置阿里云秘钥等
alicloud: access-key: xxxxxsecret-key: xxxxoss: endpoint: oss-cn-hangzhou.aliyuncs.com

定义配置bean及OSS工具类

  1. 声明配置bean
/*** 阿里云OSS配置*/
@Data
public class AliyunOssItem {private String accessKey;private String sceretKey;private String endpoint;/***  存储空间名称 */private String bucketName;/*** 上传目录*/private String uploadDir;/*** * @param accessKey* @param sceretKey* @param endpoint * @param bucketName 存储空间名称* @param uploadDir 上传目录*/public AliyunOssItem(String accessKey, String sceretKey, String endpoint, String bucketName, String uploadDir) {this.accessKey = accessKey;this.sceretKey = sceretKey;this.endpoint = endpoint;this.bucketName = bucketName;this.uploadDir = uploadDir;}/*** * @param accessKey* @param sceretKey* @param endpoint * @param bucketName 存储空间名称*/public AliyunOssItem(String accessKey, String sceretKey, String endpoint, String bucketName) {this.accessKey = accessKey;this.sceretKey = sceretKey;this.endpoint = endpoint;this.bucketName = bucketName;}
}
  1. OSS工具类
/*** 阿里云OSS上传和下载文件工具*/
@Slf4j
@UtilityClass
public class AliyunOssUtil {/*** 返回文件在OSS存储的key * @param file 上传文件* @param item OSS配置bean* @param ossClient * @return*/public static String upload2OSS(MultipartFile file, AliyunOssItem item) {OSS ossClient = new OSSClientBuilder().build(item.getEndpoint(), item.getAccessKey(), item.getSceretKey());String bucketName = item.getBucketName();String fileName = file.getOriginalFilename();// 文件名String uploadDir = item.getUploadDir();// 目录名String uploadPath = "";// 保存文件路径名称InputStream uploadInputStrem = null;if (StringUtils.isNotEmpty(uploadDir)) {uploadDir = uploadDir.substring(0, uploadDir.length()).replaceAll("\\\\", "/") + "/";}try {ensureBucket(item.getBucketName(), ossClient);// 获取上传文件后缀名String fileSuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));String md5 = MD5.getMessageDigest(file.getBytes());uploadPath = String.format("%1$s%2$s%3$s", uploadDir, md5, fileSuffix);// 创建上传Object的Metadata。ObjectMetaData是用户对该object的描述ObjectMetadata objectMetadata = new ObjectMetadata();objectMetadata.setContentLength(file.getSize());objectMetadata.setCacheControl("no-cache");objectMetadata.setContentEncoding("utf-8");objectMetadata.setContentType(getcontentType(file, fileSuffix));// 获取文件类型objectMetadata.setContentDisposition("attachment;filename=" + fileName + fileSuffix);uploadInputStrem = file.getInputStream(); // 文件输入流// 上传文件log.debug("正在上传文件到OSS...");ossClient.putObject(bucketName, uploadPath, uploadInputStrem, objectMetadata);log.debug("上传文件完成...");return uploadPath;} catch (Exception e) {log.error(e.getMessage(), e);} finally {try {if (uploadInputStrem != null) {uploadInputStrem.close();// 关闭文件流}} catch (IOException e) {e.printStackTrace();}// 关闭OSSClient。ossClient.shutdown();}return null;}/*** 判断bucket存储空间是否已建立 若未建立,先创建一个Bucket*/private void ensureBucket(String bucketName, OSS ossClient) throws OSSException {// 判断bucket是否存在boolean exists = ossClient.doesBucketExist(bucketName);if (!exists) {// log.error("bucket不存在,新建当前bucket:{}",BUCKETNAME);ossClient.createBucket(bucketName);}}/*** 根据key,从OSS上获取图片临时url* @param item OSS配置* @param key * @param expiration 过期时间(单位s)* @return*/public String downFromOSS(AliyunOssItem item, String key, int expiration) {OSS ossClient = new OSSClientBuilder().build(item.getEndpoint(), item.getAccessKey(), item.getSceretKey());try {if (StringUtils.isNotEmpty(key)) {// 设置URL过期时间Date expirationDate = new Date(System.currentTimeMillis() + expiration);// 生成URLURL url = ossClient.generatePresignedUrl(item.getBucketName(), key, expirationDate);if (null != url) {return url.toString();}}} catch (Exception e) {log.error(e.getMessage(), e);} finally {//关闭ossClient.shutdown();}return null;}/*** 判断OSS服务文件上传时文件的contentType** @param file              上传文件* @param FilenameExtension 文件后缀* @return String*/private String getcontentType(MultipartFile file, String FilenameExtension) {if (FilenameExtension.equalsIgnoreCase(".bmp")) {return "image/bmp";}if (FilenameExtension.equalsIgnoreCase(".gif")) {return "image/gif";}if (FilenameExtension.equalsIgnoreCase(".jpeg") || FilenameExtension.equalsIgnoreCase(".jpg")|| FilenameExtension.equalsIgnoreCase(".png") || FilenameExtension.equalsIgnoreCase(".jpz")) {return "image/jpeg";}if (FilenameExtension.equalsIgnoreCase(".html") || FilenameExtension.equalsIgnoreCase(".htm")|| FilenameExtension.equalsIgnoreCase(".hts")) {return "text/html";}if (FilenameExtension.equalsIgnoreCase(".txt")) {return "text/plain";}if (FilenameExtension.equalsIgnoreCase(".vsd")) {return "application/vnd.visio";}if (FilenameExtension.equalsIgnoreCase(".pptx") || FilenameExtension.equalsIgnoreCase(".ppt")) {return "application/vnd.ms-powerpoint";}if (FilenameExtension.equalsIgnoreCase(".docx") || FilenameExtension.equalsIgnoreCase(".doc")) {return "application/msword";}if (FilenameExtension.equalsIgnoreCase(".xml")) {return "text/xml";}if (FilenameExtension.equalsIgnoreCase(".xls")) {return "application/vnd.ms-excel";}if (FilenameExtension.equalsIgnoreCase(".xlsx")) {return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";}if (FilenameExtension.equalsIgnoreCase(".zip")) {return "application/zip";}return file.getContentType();}

定义UploadController和DownloadController

  1. 定义UploadController
/*** 后台文件上传接口**/
@Slf4j
@Controller
public class UploadController {/** 存储空间名称 */private static final String BUCKETNAME = "bucket-private";private static final String ROOT_DIR = "root";@Value("${spring.cloud.alicloud.access-key}")private String accessKeyId;@Value("${spring.cloud.alicloud.secret-key}")private String sceretKey;@Value("${spring.cloud.alicloud.oss.endpoint}")private String endpoint;/*** 上传至OSS* @param file* @return* @throws Exception*/@ResponseBody@PostMapping({ "/upload2OSS"})public ResponseVo<?> upload2OSS(@RequestParam(value = "file", required = false) MultipartFile file) throws Exception {if (null == file || file.isEmpty()) {throw new UploadFileNotFoundException(UploadResponseVo.Error.FILENOTFOUND);}try {SimpleDateFormat fmt = new SimpleDateFormat("yyyy/MM/dd");String dir = fmt.format(new Date());AliyunOssItem item = new AliyunOssItem(accessKeyId, sceretKey, endpoint, BUCKETNAME, ROOT_DIR + "/" + dir);String url = AliyunOssUtil.upload2OSS(file, item);if (!StringUtils.isEmpty(url)) {log.debug("上传文件至OSS后的url为:" + url);return ResultUtil.success("上传成功", url);}} catch (Exception e) {log.error(String.format("UploadController.upload%s", e));throw e;}return ResultUtil.error("上传失败!");}
}
  1. 定义DownloadController
/*** 后台文件下载接口**/
@Slf4j
@Controller
public class DownloadController {/** 存储空间名称 */private static final String BUCKETNAME = "ak-web-private";@Value("${spring.cloud.alicloud.access-key}")private String accessKeyId;@Value("${spring.cloud.alicloud.secret-key}")private String sceretKey;@Value("${spring.cloud.alicloud.oss.endpoint}")private String endpoint;@Value("${spring.cloud.alicloud.oss.expiration}")private Integer expiration;@ResponseBody@PostMapping({ "/download"})public ResponseVo<?> downloadFromOSS(String key) throws Exception {try {AliyunOssItem item = new AliyunOssItem(accessKeyId, sceretKey, endpoint, BUCKETNAME);String fileTmpUrl = AliyunOssUtil.downFromOSS(item, key, expiration);if (!StringUtils.isEmpty(fileTmpUrl)) {return ResultUtil.success("下载成功", fileTmpUrl);}} catch (Exception e) {log.error(String.format("DownloadController.downloadFromOSS%s", e));throw e;}return ResultUtil.error("下载失败!");}
}

下载接口优化为返回重定向oss路径

/*** 后台文件下载接口**/
@Slf4j
@Controller
public class DownloadController {/** 存储空间名称 */private static final String BUCKETNAME = "ak-web-private";@Value("${spring.cloud.alicloud.access-key}")private String accessKeyId;@Value("${spring.cloud.alicloud.secret-key}")private String sceretKey;@Value("${spring.cloud.alicloud.oss.endpoint}")private String endpoint;@Value("${spring.cloud.alicloud.oss.expiration}")private Integer expiration;@PostMapping({ "/download"})public String downloadFromOSS(String key) throws Exception {try {AliyunOssItem item = new AliyunOssItem(accessKeyId, sceretKey, endpoint, BUCKETNAME);String fileTmpUrl = AliyunOssUtil.downFromOSS(item, key, expiration);if (!StringUtils.isEmpty(fileTmpUrl)) {return ResultUtil.success("下载成功", fileTmpUrl);}return "redirect:" + fileTmpUrl;} catch (Exception e) {log.error(String.format("DownloadController.downloadFromOSS%s", e));throw e;}}
}

遇到的问题

The bucket you visit is not belong to you

在网上找到的解决方案有:
第一种解决办法:url中主域名后面增加bucket目录。
第二种解决办法:在bucket管理内增加安全访问域名

但是我遇到的问题是由创建的OSS上传路径中携带了"//" 造成的~~

从OSS获取临时url是http协议的

查看ClientConfiguration源码,发现默认protocol是HTTP

public class ClientConfiguration {... protected Protocol protocol = Protocol.HTTP;
}

    但是因为客户端有微信小程序,规定访问的资源必须为https协议的,所以需要将临时url变更为https协议

解决方案:知道是配置的锅,当然得从配置上下功夫喽,所以创建OSSClient时加入配置!

/**
* 获取OSSClient
* @param item
* @return
*/
private OSS getOssClient(AliyunOssItem item) {ClientBuilderConfiguration config = new ClientBuilderConfiguration();config.setProtocol(Protocol.HTTPS);return new OSSClientBuilder().build(item.getEndpoint(), item.getAccessKey(), item.getSceretKey(), config);
}

Springboot集成 阿里云OSS上传及下载相关推荐

  1. SpringBoot集成阿里云OSS上传文件

    文章目录 前言 一.准备环境 1.在搜索框搜索 对象存储OSS 2.创建Bucket 3.找到开发相关信息 二.具体代码 1.Maven依赖 2.application.yml配置 3.AliOssP ...

  2. springboot整合阿里云oss上传的方法示例

    这篇文章主要介绍了springboot整合阿里云oss上传的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 OSS申请和 ...

  3. SpringBoot整合阿里云OSS上传文件

    一.需求分析 文件上传是一个非常常见的功能,就是通过IO流将文件写到另外一个地方,这个地方可以是项目下的某个文件夹里,或者是本地电脑某个盘下面,还可以是云服务OSS里面,这里就是我要讲到的OSS,我写 ...

  4. SringBoot集成阿里云OSS上传文件

    上一篇文章讲了如何将文件从linux同步到阿里云的oss有兴趣的小伙伴可以去看看,这篇文章讲述如何将文件上传到阿里云oss上,本文只详细写出后端java代码示例,前端和无用代码都会省略,可以上传文件, ...

  5. spring boot 整合 阿里云oss上传

    Spring Boot 整合 阿里云OSS上传 OSS申请和配置 1. 注册登录 2.开通以及配置 springboot整合使用 1. 进入我们springboot的项目中,导入oss相关依赖 2. ...

  6. Nginx 代理转发阿里云OSS上传的实现代码

    这篇文章主要介绍了Nginx 代理转发阿里云OSS上传的实现代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 前言 因为小程序上传需要https,服务器https用的是 ...

  7. thinkPHP 阿里云OSS 上传文件、直接下载

    阿里云OSS 上传文件.直接下载 1. 安装OSS SDK composer require aliyuncs/oss-sdk-php 2. thinkPHP接口 public function up ...

  8. 阿里云OSS上传文件设置请求头

    之前写过一篇发送文件消息的,原生input上传文件(聊天发送文件消息),这次的需求就是更改上传地址,使用阿里云OSS上传. 如果想了解阿里云对象存储OSS是如何使用的,请看阿里云存储对象OSS使用讲解 ...

  9. 阿里云oss上传svg等格式的文件,返回的路径打开后是下载而不是预览

    在做的一个项目,阿里云oss上传svg等格式的文件,返回的路径打开后是下载而不是预览.之后web同事跟产品说不好处理,换回了使用jpg格式的文件.但是最终这个问题都是要解决的,产品要求下期也要上传sv ...

最新文章

  1. linux vi 批量修改某类字符串
  2. .NET简谈组件程序设计之(手动同步)
  3. 50 亿观众的 “云上奥运”,顶级媒体背后的数智化力量
  4. 使用腾讯云CDN做HTTPS的WordPress博客时要改的代码
  5. Web应用工作原理、动态网页技术
  6. python如何爬虫股票数据_自学python之爬虫3股票数据爬虫
  7. 弘辽科技:拼多多批发价格会影响活动价格吗?商家要不要改价?
  8. 创建VSIX项目模板
  9. android布局下划线设置,我可以在Android布局中为文本加下划线吗?
  10. 硅谷丛林的故事 EDA篇
  11. 1028: C语言程序设计教程(第三版)课后习题8.1用函数求公约数
  12. 如果《后浪》目的就是为了感动中年人呢?B站破圈之战你看懂了吗
  13. 高斯分布的积分期望E(X)方差V(X)的理论推导
  14. matlab中0和1模型,计算SBM模型,结果却不在0和1之间,求帮助!!!
  15. Probabilistic and Geometric Depth: Detecting Objects in Perspective 论文学习
  16. 基于javaweb的校园运动会管理系统(java+jsp+servlet+javabean+mysql)
  17. MySQL报错、错误代码: 1005 Can‘t create table ‘数据库名.表名‘ (errno: 150) ?
  18. SAP 消息 有关成本控制范围 XXXX的控制标志不存在
  19. “十步一杀” 消压力于无形
  20. Vue获取当前的实时时间+Vue生成计数器

热门文章

  1. domestic gpu
  2. RVO和ORCA它们是如何工作的?
  3. python 连接数据库winerror 10054_Python套接字WinError 10054
  4. 码上行动:零基础学会Python编程
  5. 矩阵可逆的充要条件及证明
  6. vue3基础(一 )composition api,typeof,keyof,keyof typeof
  7. 2019 web安全基础知识学习
  8. eNSP综合实验合集(eNSP综合大作业合集)_可先收藏
  9. onlyoffice 回调传参数_【onlyoffice中文指南】0-基本概念
  10. 分享3个高清图片素材网站