使用阿里云OSS实现文件的上传、下载、删除及修改功能

2023-10-27

一、配置OSS相关配置信息

1、要配置 OSS 相关配置信息,您可以按照以下步骤操作:

  1. 登录阿里云控制台,进入 OSS 控制台,创建一个新的 OSS Bucket,并记录下以下信息:Bucket 名称、Bucket 所属地域、AccessKey ID、Access Key Secret。
  2. 在您的 Java 项目中添加阿里云 Java SDK 依赖。您可以在项目的 pom.xml 配置文件中添加以下依赖项:
<dependency>
       <groupId>com.aliyun.oss</groupId>
       <artifactId>aliyun-sdk-oss</artifactId>
       <version>3.13.1</version>
   </dependency>
  1. 在您的 Java 代码中配置 OSS 客户端。您可以使用以下示例代码来配置 OSS 客户端:
oss:
  endpoint: https://oss-cn-yourAddress.aliyuncs.com
  accessKeyId: yourAccessKeyId
  accessKeySecret: yourAccessKeySecret
  bucketName: yourBucketName
  fileUrlPrefix: https://yourBucketName.oss-cn-hangzhou.aliyuncs.com/

2、添加OSSConfig类

这段代码定义了一个名为OSSConfig的类,它使用了注解@Value来获取配置文件中的值,并定义了一个名为ossClient的Bean,用于创建一个OSSClient对象。

具体来说,代码中的@Value注解用于从配置文件中获取oss.endpoint、oss.accessKeyId和oss.accessKeySecret的值,并将它们分别赋给endpoint、accessKeyId和accessKeySecret这三个私有变量。这样,这些变量就可以在类中被访问和使用了。

另外,代码中的@Bean注解用于告诉Spring容器,当需要一个名为ossClient的Bean时,它应该调用ossClient()方法创建一个OSSClient对象并返回给调用者。具体创建OSSClient对象的方法是使用OSSClientBuilder构建器的build()方法,传入endpoint、accessKeyId和accessKeySecret三个参数,从而创建一个连接到阿里云OSS服务的客户端对象。

@Configuration
public class OSSConfig {
    @Value("${oss.endpoint}")
    private String endpoint;
    @Value("${oss.accessKeyId}")
    private String accessKeyId;
    @Value("${oss.accessKeySecret}")
    private String accessKeySecret;
    @Bean
    public OSS ossClient() {
        return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    }
}

二、OSS实现文件的上传、下载、删除及修改功能

首先创建一个 OSSController,并注入对象

@Autowired
private OSS ossClient;
@Value("${oss.bucketName}")
private String bucketName;
@Value("${oss.fileUrlPrefix}")
private String fileUrlPrefix;

1、上传文件

  1. 方法名为upload,返回类型为Map<String, Object>,参数为MultipartFile类型的file对象,该对象代表上传的文件。

  2. 通过调用file对象的getOriginalFilename()方法获取上传文件的原始文件名,并将其赋值给fileName变量。

  3. 使用UUID生成一个唯一的对象名称objectName,以保证上传的文件不会覆盖已有的文件。objectName的值由UUID和文件后缀名组成,例如:f6d8b25a-d6b0-4b7b-8d6a-0e1f7c1a3a9a.jpg。

  4. 通过file.getInputStream()方法获取上传文件的InputStream对象,使用该对象来上传文件到OSS中。

  5. 调用阿里云Java SDK提供的putObject方法上传文件,并将上传结果赋值给result变量。

  6. 将上传文件的URL地址和文件名放入HashMap对象data中,其中fileUrlPrefix是OSS中存储文件的URL前缀,例如:https://my-bucket.oss-cn-hangzhou.aliyuncs.com/。

  7. 打印上传成功的信息,返回data对象。

  8. 如果上传过程出现异常,将异常信息打印出来,并抛出该异常。

@ApiOperation("上传文件")
@Log(value = "上传文件")
@PostMapping("/upload")
public Map<String, Object> upload(@RequestPart("file") MultipartFile file) throws IOException {
    String fileName = file.getOriginalFilename();
    assert fileName != null;
    String objectName = UUID.randomUUID().toString() + fileName.substring(fileName.lastIndexOf("."));
    try (InputStream inputStream = file.getInputStream()) {
        PutObjectResult result = ossClient.putObject(bucketName, objectName, inputStream);
        Map<String, Object> data = new HashMap<>();
        data.put("fileUrl", fileUrlPrefix + objectName);
        System.out.println("File " + fileName + " was uploaded successfully to OSS.");
        return data;
    } catch (OSSException oe) {
        System.out.println("Error uploading file " + fileName + " to OSS: " + oe.getMessage());
        throw oe;
    }
}

2、下载文件

  1. 生成带有过期时间的 URL,有效期为 3600 秒。这里使用了 ossClient 的 generatePresignedUrl 方法,传入了 bucketName 和 objectName,以及过期时间 expiration。生成的 URL 可以用于临时访问 OSS 对象。

  2. 将 URL 设置为另存为链接。这里将原 URL 拼接上了一个参数 download,以及文件名 objectName 的 URL 编码版本,用于告诉浏览器将文件另存为。

  3. 设置 Content-Disposition 响应头。这里设置了 Content-Type 为 application/octet-stream,表示下载的文件是一个二进制流;同时设置 Content-Disposition 为 inline,表示浏览器会直接显示文件内容,并且指定文件名为 objectName 的 URL 编码版本。

  4. 将用户重定向到另存为链接。这里使用了 response 的 sendRedirect 方法,将下载链接返回给客户端。

  5. 如果下载失败,会捕获 OSSException 异常,并输出错误信息。

@ApiOperation("下载文件")
@Log(value = "下载文件")
@GetMapping("/download")
public void download(String objectName, HttpServletResponse response) throws IOException {
    try {
        // 生成带有过期时间的 URL,有效期为 3600 秒
        Date expiration = new Date(2694655614L);
        URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
        // 将 URL 设置为另存为链接
        String downloadUrl = url.toString() + "&download=" + URLEncoder.encode(objectName, "UTF-8");
        // 设置 Content-Disposition 响应头
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(objectName, "UTF-8"));
        // 将用户重定向到另存为链接
        response.sendRedirect(downloadUrl);
        System.out.println("Object " + objectName + " was downloaded successfully.");
    } catch (OSSException oe) {
        System.out.println("Error downloading object " + objectName + ": " + oe.getMessage());
    }
}

3、删除文件

在方法体中,先调用ossClient对象的deleteObject方法来删除指定名称的对象。如果删除成功,则打印一条消息表示删除成功;否则,捕获OSSException异常,并打印一条错误消息,其中包含异常的详细信息。

@ApiOperation("删除文件")
@Log(value = "删除文件")
@DeleteMapping("/delete")
public void delete(String objectName) {
    try {
        ossClient.deleteObject(bucketName, objectName);
        System.out.println("Object with name " + objectName + " was deleted successfully.");
    } catch (OSSException oe) {
        System.out.println("Error deleting object with name " + objectName + ": " + oe.getMessage());
    }
}

4、修改文件名称

1.将指定的对象从一个bucket复制到另一个bucket,并将复制后的对象命名为newObjectName。复制操作的结果存储在CopyObjectResult对象中。

2.将新的复制对象的访问权限设置为PublicRead,即公开读取权限。

3.删除原始对象,即将原始对象从bucket中删除。

总体来说,实现了将一个对象从一个bucket复制到另一个bucket,并将访问权限设置为公开,并删除原始对象。

@ApiOperation("修改文件名称")
@Log(value = "修改文件名称")
@DeleteMapping("/renameFile")
public void renameFile(String objectName, String newObjectName) throws OSSException {
    try {
        // 复制对象并将其设置为公共读取权限
        CopyObjectResult result = ossClient.copyObject(bucketName, objectName, bucketName, newObjectName);
        ossClient.setObjectAcl(bucketName, newObjectName, CannedAccessControlList.PublicRead);
        // 删除原始对象
        ossClient.deleteObject(bucketName, objectName);
        System.out.println("Object " + objectName + " was renamed to " + newObjectName + " successfully.");
    } catch (OSSException oe) {
        System.out.println("Error renaming object " + objectName + ": " + oe.getMessage());
    }
}

调试

最后打开Swegger2的文档http://localhost:8080/api/doc.html可进行文件的上传、下载、删除及修改文件名称的调试
在这里插入图片描述

小知识点

@RequestPart和@RequestParam的区别

@RequestPart@RequestParam 都是 Spring MVC 中用于处理 HTTP 请求参数的注解,但它们的使用场景有所不同。

  1. @RequestParam 注解主要用于处理 URL 参数或表单数据,在 GET 或 POST 请求中都可以使用,其使用方式如下:
@GetMapping("/example")
public void example(@RequestParam("param1") String param1, @RequestParam("param2") int param2) {
    // ...
}

在上面的示例代码中, @RequestParam 注解用于将 HTTP 请求中的 param1param2 参数解析为方法参数中的 param1param2 变量。

  1. @RequestPart 注解主要用于处理请求体中的文件上传、JSON 数据等,常用于处理 multipart/form-data 格式数据,在 POST 请求中使用,其使用方式如下:
@PostMapping("/upload")
public void upload(@RequestPart("file") MultipartFile file) {
    // ...
}

在上面的示例代码中, @RequestPart 注解用于将 HTTP 请求体中的 file 参数解析为方法参数中的 file 变量。

需要注意的是, @RequestPart 注解常用于处理 multipart/form-data 格式数据,如果请求是 application/json 或其他格式的数据,应该使用 @RequestBody 注解来处理。此外, @RequestPart 还可以与 Swagger 等 API 文档工具一起使用来生成 API 文档。
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用阿里云OSS实现文件的上传、下载、删除及修改功能 的相关文章

  • 哪个 new 首先执行——在构造函数中还是在构造函数外?

    如果我定义一个类如下 public class myClass private x new anotherClass private y public myClass y new anotherClass 哪个变量会更早获得实例 x 或 y
  • android-透明RelativeLayout

    我想要制作一个具有可绘制渐变作为背景的活动 并将在其背景顶部显示 4 个面板 相对布局 现在我想让 4 个面板透明 例如 50 以便也可以看到渐变背景 我搜索了谷歌 但我发现只能通过活动而不是布局来做到这一点 如何做我想做的事 您可以创建一
  • 将json URL导入到java并使用jackson库解析它

    我正在尝试读取 java 中的 json 链接并解析它 以便我可以将它用于其他事务 但问题是我收到错误 我真的不知道该如何处理它们 这是代码 package weather data import weather data import c
  • Spring Batch 多线程

    我正在编写一个 Spring Batch 并希望在需要时对其进行扩展 我的 ApplicationContext 看起来像这样 Configuration EnableBatchProcessing EnableTransactionMan
  • 使用Optional作为类中的属性是一个好习惯吗? [复制]

    这个问题在这里已经有答案了 我读过一些关于目的的内容Optional 不幸的是我不记得在哪里 在Java 8中 我很惊讶作者没有提到使用Optional作为类中的属性 由于我在课堂上经常使用选项 我想知道这是否是一个好的做法 或者我可以更好
  • com.google.gwt.dev.jjs.InternalCompilerException:访问期间出现意外错误

    我在使用版本 2 6 0 编译 gwt 应用程序时遇到以下错误 最初我用 gwt 版本 2 6 1 的 maven 编译它 然后尝试通过版本 2 6 0 的 eclipse 编译它 跟版本兼容有关系吗 com google gwt dev
  • 全屏独占模式下的 AWT 框架在窗口弹出对话框中最小化

    我正在开发一个在全屏独占模式下使用 awt 框架的应用程序 一切正常 直到弹出窗口可见 这会抢走焦点 我的应用程序将被最小化 这是我的框架的初始化代码 if ApplicationConfig getInstance useFullscre
  • Hibernate HQL 查询:如何将集合设置为查询的命名参数?

    给定以下 HQL 查询 FROM Foo WHERE Id id AND Bar IN barList I set id使用查询对象的setInteger 方法 我想设置 barList用一个List对象 但查看 Hibernate 文档和
  • 找不到模块:javafx.controls

    我已经下载了JavaFX SDK 解压它并设置PATH TO FX系统变量 如下本说明 https openjfx io openjfx docs install javafx 我使用了以下代码示例 import javafx applic
  • 内容安全策略:页面设置阻止自行加载资源?

    我有基于 Java 的 Web 应用程序运行在Tomcat http en wikipedia org wiki Apache Tomcat6 我的应用程序在本地主机和端口 9001 上运行 为了使我的应用程序更加安全并降低风险XSS ht
  • 为什么我无法解开根节点并反序列化对象数组?

    为什么我无法通过展开根节点来反序列化对象数组 import java io IOException import java util Arrays import java util List import org codehaus jack
  • 如何在Android Studio中关联.mp3文件

    我想根据列表视图项单击播放 mp3 文件 但是根据我的代码 我运行我的应用程序 出现此窗口 因此由于缺少音频选项 我真的不知道需要选择其中哪一个为了关联我的 mp3 文件 mainList setOnItemClickListener ne
  • 如何更改tomcat jmx密码的文件权限

    我正在尝试保护 Windows 平台上托管的本地 tomcat 实例上的 JMX 访问 我已经创建了访问权限和密码文件 并使用以下 VM 参数插入这些文件 Dcom sun management jmxremote password fil
  • 使用JPanel绘制直线并获取点坐标

    我现在完全不知所措 我没有太多用 Java 构建 GUI 我一直在阅读有关 swing 和 JPanel 的所有内容 我认为我想做的事情是可能的 我只是还没有弄清楚how 我正在尝试构建一个 GUI 您可以在其中在某个绘图区域内绘制直线 我
  • Spring @Configuration如何缓存对bean的引用

    使用基于 Java 的配置时 Spring 如何防止再次调用 bar 我想知道编译时注释处理或通过代理方法 Configuration public class AppConfig Bean public Foo foo return ne
  • Java 通用问题

    下面的代码可以编译 但如果我取消注释行 它不会编译 我很困惑为什么 HashMap 确实扩展了 AbstractMap 并且声明映射的第一行可以正常编译 import java util AbstractMap import java ut
  • 在 Java Jersey 2 JAX-RS 中初始化单例

    我是泽西岛 2 22 2 的新手 请耐心等待 我正在创建一个与 LDAP 服务器交互的 REST 服务 用于存储 删除和检索用户数据 该服务通过执行加密 解密充当安全中介 在使用 REST 服务之前必须进行相当多的初始化 并且我只想执行此初
  • 如果可能,将 jFrame 输出到第二台显示器

    我在 Java 中的 Swing 上有一个 jFrame 我希望它输出到第二个监视器 如果该监视器存在 我尝试过这个 通过this http download oracle com javase 6 docs api java awt Gr
  • LinkedBlockingQueue 抛出 InterruptedException

    我有这段代码 ALinkedBlockingQueue应该只抛出一个Exception如果在等待添加到队列时被中断 但这个队列是无限的 所以它应该尽快添加 为什么我的关闭方法会抛出一个InterruptedException private
  • Ant 类路径和 junit.jar

    我有一个 build xml 它允许我运行 junit 测试 这是相关部分

随机推荐

  • React 路由使用-详细介绍

    路由初使用 抽象路由模块 src page Article index js const Article gt return div p 文章页 p div export default Article src router index j
  • selenium框架解析

    seleium框架解析 文章目录 seleium框架解析 前言 一 selenium驱动浏览器原理 二 selenium常用操作 1 四大操作 2 三大切换 3 三大等待 4 下拉框操作 5 时间控件操作 6 滚动条操作 7 文件操作 前言
  • java类的静态成员和非静态成员_Java SE之[静态成员/类成员]与[非静态成员/实例成员]【static】...

    定义 静态成员 又称类成员 使用static修饰符的方法和变量 非静态成员 又称实例成员 未使用static修饰符的方法和变量 结论 注 jdk1 8 测试源码 public class Main private int x 34 非静态变
  • linux path 多个目录,Linux下多路径Multipath的简单配置

    Linux下多路径Multipath的简单配置 1 启用Multipath 1 启动multipathd服务 service multipathd start 或者 etc init d multipathd start 2 修改multi
  • python房价预测_Python——决策树实战:california房价预测

    Python 决策树实战 california房价预测 编译环境 Anaconda Jupyter Notebook 首先 导入模块 1 importpandas as pd2 importmatplotlib pyplot as plt3
  • 手写算法-python代码实现Kmeans

    手写算法 python代码实现Kmeans 原理解析 代码实现 实例演示 sklearn对比 总结 原理解析 今天 我们来讲一下Kmeans 一种无监督聚类算法 也是最为经典的基于划分的聚类方法 它的思想是 对于给定的样本集 按照样本之间的
  • java中的 Set转List

    构造Map数据 Map
  • Mysql详解

    一 数据库的基本概念 数据库的英文单词 DataBase DB 数据库 用来存储和管理数据的仓库 数据库的特点 持久化存储数据 其实数据库就是一个文件系统 方便存储和管理数据 使用了统一的方式操作数据库 SQL 常见的数据库软件 MySQL
  • 两阶段最小二乘法_最小二乘法(Least Squares)简介

    最小二乘法简介 最小二乘法 Least Squares 是回归分析中的一种标准方法 它是用来近似超定系统 Overdetermined System 答案的一种方法 超定系统是指数学中的一种概念 一组包含未知数的方程组中 如果方程的数量大于
  • arm平台编译adb

    参考github https github com bonnyfone adb arm 本来的目的是在arm平台编译以后能够使用adb shell获取shell权限 然后就可以避开其他权限无法执行su的问题 最开始 先修改了android源
  • kodi刮削器 中文_手把手教您设置KODI播放器,3分钟打造家庭影院级媒体库,流畅播放NAS里的原盘电影!...

    创作立场声明 此文为比较基础的KODI播放器的保姆级安装和配置教程 希望可以帮助一些初入家庭影音的值友们 关于KODI KODI是一款播放器 也是一款媒体库管理软件 不仅在电视上可以安装 还可以在windows电脑上进行安装 当下载高清 高
  • Vue3记录

    Vue3快速上手 1 Vue3简介 2020年9月18日 Vue js发布3 0版本 代号 One Piece 海贼王 耗时2年多 2600 次提交 30 个RFC 600 次PR 99位贡献者 github上的tags地址 https g
  • 【1】TypeScript入门——基本认知

    一 基本认知 1 优点 TypeScript 更加可靠 它与使用 JavaScript 相比 不仅支持在任何地方直观地获取组件的接口定义 还能对属性 状态中的值是否为空进行自动检测并给出提示 容错处理 甚至还支持对 React JSX元素接
  • Java创建数组的方法

    最近学Java 一点小心得 希望和大家分享一下 第一次写文章 写的不好希望大家谅解 当然我也会尽力写好这篇文章 Java创建数组的方法大致有三种 说明 这里以int为数据类型 以arr为数组名来演示 一 声明并赋值 int arr 1 2
  • 嵌入式学习——c语言数据的输入输出

    嵌入式学习 c语言数据的输入输出 一 输入输出概念 1 2C语言本身不提供输入输出语句 1 3 include头文件放在程序中 二 printf输出数据 2 2格式字符 三 scanf输入数据 3 1scanf一般格式 四 输入输出函数 4
  • Spring Boot之分离测试和生产环境的应用配置

    多环境应用配置 将默认不变的配置 设置在application properties文件中 新建开发环境下的属性文件application dev properties 将开发中的配置 设置在该文件中 新建生产环境下的属性文件applica
  • “点两下”就能开发一个AI应用!百度砸亿元基金、千万算力要搞插件生态

    金磊 发自 武汉量子位 公众号 QbitAI 这年头 要想开发一个AI应用 怎么搞 只需要简单的 点击 动作就可以了 例如你想开发一个AI作画的App 只需要先点击与之相匹配的能力 简笔成画 根据手绘草图和语言 生成符合要求的图片 言语之美
  • fiddler设置好代理后不能上网(方法二)

    1 打开fiddler在工具栏找到Tools gt options Connections选项如下图 将Allow remote computers to connect 勾选上 然后记住默认8888这个端口 可更改 设置手机代理时会用到
  • 2023高教社数学建模国赛A题 - 定日镜场的优化设计 - 思路

    问题1 计算年平均光学效率和输出热功率 建立模型的坐标系 以圆形区域中心为原点 正东方向为x轴 正北方向为y轴 垂直地面向上为z轴 计算吸收塔和定日镜的位置 吸收塔建于圆形定日镜场中心 根据给定的数据确定定日镜的位置 计算每个定日镜的光学效
  • 使用阿里云OSS实现文件的上传、下载、删除及修改功能

    一 配置OSS相关配置信息 1 要配置 OSS 相关配置信息 您可以按照以下步骤操作 登录阿里云控制台 进入 OSS 控制台 创建一个新的 OSS Bucket 并记录下以下信息 Bucket 名称 Bucket 所属地域 AccessKe