SpringBoot 文件上传(三)

之前讲解了如何接收文件以及如何保存到服务端的本地磁盘中:

SpringBoot 文件上传(一)-CSDN博客

SpringBoot 文件上传(二)-CSDN博客

这节讲解如何利用阿里云提供的OSS(Object Storage Service)对象存储服务保存文件。

阿里云是阿里巴巴集团旗下全球领先的云计算公司,也是国内最大的云服务提供商 。

云服务指的就是通过互联网对外提供的各种各样的服务,比如像:语音服务、短信服务、邮件服务、视频直播服务、文字识别服务、对象存储服务等等。

当我们在项目开发时需要用到某个或某些服务,就不需要自己来开发了,可以直接使用阿里云提供好的这些现成服务就可以了。比如:在项目开发当中,我们要实现一个短信发送的功能,如果我们项目组自己实现,将会非常繁琐,因为你需要和各个运营商进行对接。而此时阿里云完成了和三大运营商对接,并对外提供了一个短信服务。我们项目组只需要调用阿里云提供的短信服务,就可以很方便的来发送短信了。这样就降低了我们项目的开发难度,同时也提高了项目的开发效率。(大白话:别人帮我们实现好了功能,我们只要调用即可)

云服务提供商给我们提供的软件服务通常是需要收取一部分费用的。

阿里云对象存储OSS(Object Storage Service),是一款海量、安全、低成本、高可靠的云存储服务。使用OSS,您可以通过网络随时存储和调用包括文本、图片、音频和视频等在内的各种文件。

在我们使用了阿里云OSS对象存储服务之后,我们的项目当中如果涉及到文件上传这样的业务,在前端进行文件上传并请求到服务端时,在服务器本地磁盘当中就不需要再来存储文件了。我们直接将接收到的文件上传到oss,由 oss帮我们存储和管理,同时阿里云的oss存储服务还保障了我们所存储内容的安全可靠。

云服务的运用思路

其实不管是哪个第三方提供的服务,以及服务的不同类别,我们使用服务的思路是一样的。

SDK:Software Development Kit 的缩写,软件开发工具包,包括辅助软件开发的依赖(jar包)、代码示例等,都可以叫做SDK。

简单说,sdk中包含了我们使用第三方云服务时所需要的依赖,以及一些示例代码。我们可以参照sdk所提供的示例代码就可以完成入门程序。

 推荐将SDK提供的入门程序读明白后,开发一个专门使用该服务的接口,之后可以直接调用,提供复用性。

阿里云OSS对象存储服务使用

第三方服务使用的通用思路,我们做一个简单介绍之后,接下来我们就来介绍一下我们当前要使用的阿里云oss对象存储服务具体的使用步骤。

Bucket:存储空间是用户用于存储对象(Object,就是文件)的容器,所有的对象都必须隶属于某个存储空间。把它当成文件夹也可以。

改写SDK入门程序为文件上传接口

在对象存储OSS服务界面中找到API和SDK

一直翻到SDK示例部分,浏览Java SDK示例

在Maven项目中配置依赖安装SDK(软件开发工具包)

<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.15.1</version>
</dependency>
<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.1</version>
</dependency>
<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.3.3</version>
</dependency>

浏览SDK提供的文件上传入门程序

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import java.io.ByteArrayInputStream;

public class Demo {

    public static void main(String[] args) throws Exception {
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "examplebucket";
        // 填写Object完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
        String objectName = "exampledir/exampleobject.txt";

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

        try {
            String content = "Hello OSS";
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}

根据这个文件,修改后得到OSS上传工具类,这个类保存在utils包中,在IOC中不属于三种情况,所以用@Component注释

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;

@Component
public class AliOSSUtils {
    private String endpoint = "https://oss-cn-shanghai.aliyuncs.com";
    private String accessKeyId = "LTAI5t9MZK8iq5T2Av5GLDxX";
    private String accessKeySecret = "C0IrHzKZGKqU8S7YQcevcotD3Zd5Tc";
    private String bucketName = "web-framework01";

    /**
     * 实现上传图片到OSS
     */
    public String upload(MultipartFile multipartFile) throws IOException {
        // 获取上传的文件的输入流
        InputStream inputStream = multipartFile.getInputStream();

        // 避免文件覆盖
        String originalFilename = multipartFile.getOriginalFilename();
        String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));

        //上传文件到 OSS
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        ossClient.putObject(bucketName, fileName, inputStream);

        //文件访问路径
        String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;

        // 关闭ossClient
        ossClient.shutdown();
        return url;// 把上传到oss的路径返回
    }
}

改写后的upload方法如下:

import com.itheima.pojo.Result;
import com.itheima.utils.AliOSSUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;

@Slf4j
@RestController
public class UploadController {

    @Autowired
    private AliOSSUtils aliOSSUtils;

    @PostMapping("/upload")
    public Result upload(MultipartFile image) throws IOException {
        //调用阿里云OSS工具类,将上传上来的文件存入阿里云
        String url = aliOSSUtils.upload(image);
        //将图片上传完成后的url返回,用于浏览器回显展示
        return Result.success(url);
    }
    
}

注意,服务端返回的是文件链接,是阿里云给每个文件创建的链接。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/485452.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux升级GCC

文章目录 一、安装 EPEL 仓库二、更新yum三、安装 CentOS 开发工具组四、安装scl五、安装gcc 11六、启用gcc 11七、设置永久使用 一、安装 EPEL 仓库 命令&#xff1a; yum install epel-release -y二、更新yum 命令&#xff1a; yum update -y三、安装 CentOS 开发工具组 …

Unity 背包系统中拖拽物体到指定位置或互换位置效果的实现

在Unity中&#xff0c;背包系统是一种常见的游戏系统&#xff0c;可以用于管理和展示玩家所持有的物品、道具或装备。 其中的拖拽功能非常有意思&#xff0c;具体功能就是玩家可以通过拖拽物品图标来移动物品在背包中的位置&#xff0c;或者将物品拖拽到其他位置或界面中&…

【数据结构和算法初阶(C语言)】二叉树的链式结构--前、中、后序遍历实现详解,节点数目计算及oj题目详解---二叉树学习日记③

1.二叉树的链式存储 二叉树的链式存储结构是指&#xff0c;用链表来表示一棵二叉树&#xff0c;即用链来指示元素的逻辑关系。 通常的方法是 链表中每个结点由三个域组成&#xff0c;数据域和左右指针域&#xff0c;左右指针分别用来给出该结点左孩子和右孩子所 在的链结点的存…

20240319-图论

图论练习题目 拓扑排序深度优先搜索方法广度优先搜索方法 无向无权图无向有权图有向无权图 利用广度优先搜索算法有向有权图 带排序的广度优先算法/dijkstra最小生成树prims算法Kruskals Algorithm 最小割 min-cut二分图 Bipartite Graph 队列例题1 所有可能的路径例题2 岛屿数…

Redis 教程系列之Redis 集群配置(十三)

1.Redis集群方案比较 主从模式 在软件的架构中,主从模式(Master-Slave)是使用较多的一种架构。主(Master)和从(Slave)分别部署在不同的服务器上,当主节点服务器写入数据时,同时也会将数据同步至从节点服务器,通常情况下,主节点负责写入数据,而从节点负责读取数据。…

【计算机网络_网络层】IP协议

文章目录 1. IP的基本概念1.1 什么是IP协议1.2 为什么要有IP协议 2. IP的协议格式3. 网段划分&#xff08;重要&#xff09;3.1 为什么要进行网段划分3.2 网段划分的规则3.2.1 古老的划分方案3.2.2 现代的划分方案 4. 特殊的IP地址5. 解决IP地址的数量限制问题6. 私有IP和公网I…

RecyclerView notifyItemRemoved 之后的源码分析

源码版本&#xff1a;androidx1.3.2 分析场景&#xff1a; RecyclerView使用线性布局&#xff0c;方向为竖直方向&#xff0c;布局从上到下&#xff0c;宽高都是 MATCH_PARENT。开始有3条数据。然后移除 position 1 的数据。 流程图 先说下结论&#xff1a; 在 dispatchL…

24. UE5 RPG制作属性面板(二)

在上一篇中&#xff0c;我们创建属性面板的大部分样式&#xff0c;这一篇里面接着制作。 在这一篇里我们需要有以下几个方面&#xff1a; 在界面增加一个属性按钮。属性按钮增加事件&#xff0c;点击时可以打开属性面板&#xff0c;属性面板打开时无法再次点击按钮。点击属性面…

操作系统究竟是什么?在计算机体系中扮演什么角色?

操作系统究竟是什么&#xff1f;在计算机体系中扮演什么角色&#xff1f; 一、操作系统概念二、操作系统如何管理软硬件资源2.1 何为管理者2.2 操作系统如何管理硬件 三、系统调用接口作用四、用户操作接口五、广义操作系统和狭义操作系统 一、操作系统概念 下面是来自百度百科…

动态规划Dynamic Programming

上篇文章我们简单入门了动态规划&#xff08;一般都是简单的上楼梯&#xff0c;分析数据等问题&#xff09;点我跳转&#xff0c;今天给大家带来的是路径问题&#xff0c;相对于上一篇在一维中摸爬滚打&#xff0c;这次就要上升到二维解决问题&#xff0c;但都用的是动态规划思…

STM32微控制器中,如何处理多个同时触发的中断请求?

在STM32微控制器中&#xff0c;处理多个同时触发的中断请求需要一个明确的中断优先级策略&#xff0c;以确保关键任务能够及时得到响应。STM32的中断控制器&#xff08;NVIC&#xff09;支持优先级分组&#xff0c;允许开发者为不同的中断设置抢占优先级和子优先级。本文将详细…

Matlab|【免费】智能配电网的双时间尺度随机优化调度

目录 1 主要内容 基础模型 2 部分代码 3 部分程序结果 4 下载链接 1 主要内容 该程序为文章《Two-Timescale Stochastic Dispatch of Smart Distribution Grids》的源代码&#xff0c;主要做的是主动配电网的双时间尺度随机优化调度&#xff0c;该模型考虑配电网的高效和安…

JAVA面向对象编程 JAVA语言入门基础

类与对象的概念 类 (Class) 和对象 (Object) 是面向对象程序设计方法中最核心的概念。 类是对某一类事物的描述(共性)&#xff0c;是抽象的、概念上的定义&#xff1b;而对象则是实际存在的属该类事物的具体的个体&#xff08;个性&#xff09;&#xff0c;因而也称为实例(In…

网络协议栈--传输层--UDP/TCP协议

目录 本节重点一、再谈端口号1.1 再谈端口号1.2 端口号范围划分1.3 认识知名端口号(Well-Know Port Number)1.4 回答两个问题1.5 netstat1.6 pidof 二、UDP协议2.1 UDP协议段格式2.2 UDP的特点2.3 面向数据报2.4 UDP的缓冲区2.5 UDP使用注意事项2.6 基于UDP的应用层协议2.7 UDP…

知攻善防应急靶场-Linux(2)

前言&#xff1a; 堕落了三个月&#xff0c;现在因为被找实习而困扰&#xff0c;着实自己能力不足&#xff0c;从今天开始 每天沉淀一点点 &#xff0c;准备秋招 加油 注意&#xff1a; 本文章参考qax的网络安全应急响应和知攻善防实验室靶场&#xff0c;记录自己的学习过程&am…

JAVA学习笔记20(面向对象编程)

1.3 方法递归调用 ​ *阶乘 public int factorial(int n) {if(n 1){return 1;}else{return factorial(n-1)*n;} }1.递归重要规则 1.执行一个方法时&#xff0c;就创建一个新的受保护的独立空间&#xff08;栈空间&#xff09; 2.方法的局部变量是独立的&#xff0c;不会相互…

反序列化漏洞简单知识

目录&#xff1a; 一、概念&#xff1a; 二、反序列化漏洞原因 三、序列化漏洞的魔术方法&#xff1a; 四、反序列化漏洞防御&#xff1a; 一、概念&#xff1a; 序列化&#xff1a; Web服务器将HttpSession对象保存到文件系统或数据库中&#xff0c;需要采用序列化的…

Cobalt Strike -- 各种beacon

今天来讲一下cs里面的beacon 其实cs真的功能很强大&#xff0c;自带代理创建&#xff0c;自带beacon通信&#xff01;&#xff01;&#xff01; 一张图&#xff0c;就能说明beacon的工作原理 1.Beacon 每当有一台机器上线之后&#xff0c;我们都会选择sleep时间&#xff0c;…

代码随想录算法训练营Day56 ||leetCode 583. 两个字符串的删除操作 || 72. 编辑距离

647. 回文子串 dp[i][j]表示第i位开始&#xff0c;第j位结束的字符串是否为回文串 class Solution { public:int countSubstrings(string s) {vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));int result 0;for (int i s.size() - 1…

Redis 教程系列之Redis PHP 使用 Redis(十二)

PHP 使用 Redis 安装 开始在 PHP 中使用 Redis 前&#xff0c; 我们需要确保已经安装了 redis 服务及 PHP redis 驱动&#xff0c;且你的机器上能正常使用 PHP。 接下来让我们安装 PHP redis 驱动&#xff1a;下载地址为:https://github.com/phpredis/phpredis/releases。 P…