10分钟带你学会阿里OSS对象存储
一. 前言
最近有很多小伙伴问健哥,如果我们要进行大规模的文件存储该怎么做?
其实实现文件存储的技术有很多,如果我们在网上搜索一下,你会发现实现的技术简直是五花八门,比如有一种技术叫FastDFS就可以实现文件存储,但该方案需要自己搭建服务器,非常的麻烦。
实际上现在很多公司都在使用腾讯云或者阿里云技术,比如阿里云就提供了OSS对象存储技术,该技术安全可靠且用起来简单的要死,只需10分钟就可以上手搞定存储。什么?你不信?!那就跟着健哥一步步来,如果健哥带你10分钟搞定文件存储,你就给我点个赞呗!
二. 浅析OSS对象存储作用
在学习OSS具体实现之前,我们先来简单了解一下OSS是怎么个东东吧。
阿里云对象存储OSS,简单地说就是我们花钱在阿里购买一块存储空间,然后我们就可以将图片、音频、视频等各种文件资源存储在对象存储OSS服务器上。接着对象存储OSS服务器就可以供有权限的人员上传、下载、删除这些文件。
所以有了OSS,我们就省去了购买硬件存储服务器、搭建存储服务器、运营管理存储服务器等一系列的繁琐操作了。
有了这些基本的了解之后,我们就可以开始使用OSS了。当然,首先我们得购买OSS服务!
三. 对象存储OSS注册和配置
阿里云对象存储OSS官网地址 :
https://cn.aliyun.com/product/oss
3.1 注册和登录
进入阿里云官网后,首先就是注册和登录,我们可以使用自己的支付宝账号登录,可以在阿里云手机客户端扫码登录,或者用账号密码登录,总之阿里云提供了多种登录形式。基本上阿里旗下的产品,用自己的支付宝账号都可以通用。
3.2 开通对象存储OSS服务
首先我们找到阿里云的对象存储OSS服务,点击进入。
点击开通按钮,开通对象存储OSS服务。
3.3 管理控制台
注册、登录、开通OSS服务后,点击管理控制台,进入控制台界面。
接着进入到控制台界面。
这里我们要先创建一个Bucket桶,点击Bucket列表菜单,点击创建Bucket按钮,然后按照下面的内容填写即可。大家要注意,Bucket桶的名称要唯一,不能重复。
3.4 使用控制台上传图片
创建完Bucket桶后,我们就可以使用控制台上传文件进行测试了,上传操作如下:
成功上传一张图片的结果如下:
四. 代码实现
当然,我们在开发的时候,肯定不会这样手动上传文件,主要是利用代码进行实现。
4.1 搭建项目环境
我们先创建一个项目,名称就叫做aliyunossDemo吧。这里我们当然是利用Maven创建项目,大家记得不要选择使用Maven自带的骨架哦。
接下来在pom.xml中导入依赖包。
<!-- 继承Spring boot工程 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.5.RELEASE</version> </parent> <properties> <!-- 项目源码及编译输出的编码 --> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <!-- 项目编译JDK版本 --> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <!-- 依赖包版本管理 --> <spring.boot.version>2.1.5.RELEASE</spring.boot.version> <aliyun-oss-version>3.10.2</aliyun-oss-version> <httpcore-verison>4.4.3</httpcore-verison> <httpclient-version>4.5.1</httpclient-version> </properties> <dependencies> <!-- Spring boot starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${spring.boot.version}</version> </dependency> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>${aliyun-oss-version}</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>${httpcore-verison}</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>${httpclient-version}</version> </dependency> </dependencies>
注意,如果你的JDK是1.9或者以上版本,需要加入jaxb相关依赖,其他JDK版本不需要!
<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>
然后我们在resources目录下创建一个application.yml配置文件。
spring: servlet: multipart: max-file-size: 10MB max-request-size: 10MB application: name: aliyun-oss-demo server: port: 9001 aliyun: oss: #服务器地址, 我选择的是华北2-北京地址如下 endpoint: http://oss-cn-beijing.aliyuncs.com #子账户名称,在自己控制台账户的Access中查看 accessKeyId: 填写自己的accessKey #子账户密码 accessKeySecret: 填写自己的accessSecret #自己创建的桶的名字 bucketName: qianfeng-file
接着我们创建一个启动类AliyunOssApplication。
package com.qianfeng; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * 微服务启动类 * @Author 千锋健哥 */ @SpringBootApplication public class AliyunOssApplication { public static void main(String[] args) { SpringApplication.run(AliyunOssApplication.class, args); } }
4.2 封装工具类
创建com.qianfeng.util包,放入文件操作工具类AliyunOSSUtil。
package com.qianfeng.util; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClient; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.model.*; import java.io.ByteArrayInputStream; import java.io.File; import java.io.InputStream; import java.util.Date; /** * 阿里云OSS上传,下载, 删除文件工具类 * @Author 千锋健哥 */ public class AliyunOSSUtil { /** * byte数组格式上传文件 * @param endpoint OSS对外服务的访问域名 * @param accessKeyId accessKey账号 * @param accessKeySecret accessKey密码 * @param bucketName 桶名字 * @param objectName 完整文件名, 例如abc/efg/123.jpg * @param content 文件内容, byte数组格式 * @Author 千锋健哥 */ public static void uploadByByteArrayFile(String endpoint, String accessKeyId, String accessKeySecret, String bucketName, String objectName, byte[] content) throws Exception { // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); //创建上传请求对象 PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new ByteArrayInputStream(content)); // 上传 PutObjectResult putObjectResult = ossClient.putObject(putObjectRequest); // 关闭OSSClient。 ossClient.shutdown(); } /** * 输入流格式上传文件 * @param endpoint OSS对外服务的访问域名 * @param accessKeyId accessKey账号 * @param accessKeySecret accessKey密码 * @param bucketName 桶名字 * @param objectName 完整文件名, 例如abc/efg/123.jpg * @param content 文件内容, 输入流格式 * @Author 千锋健哥 */ public static void uploadByInputStreamFile(String endpoint, String accessKeyId, String accessKeySecret, String bucketName, String objectName, InputStream content) { // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 上传 ossClient.putObject(bucketName, objectName, content); // 关闭OSSClient ossClient.shutdown(); } /** * byte数组格式上传文件并返回上传后的URL地址 * @param endpoint OSS对外服务的访问域名 * @param accessKeyId accessKey账号 * @param accessKeySecret accessKey密码 * @param bucketName 桶名字 * @param objectName 完整文件名, 例如abc/efg/123.jpg * @param content 文件内容, byte数组格式 * @Author 千锋健哥 */ public static String uploadImage(String endpoint, String accessKeyId, String accessKeySecret, String bucketName, String objectName, byte[] content) throws Exception { // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 创建上传文件的元信息,可以通过文件元信息设置HTTP header(设置了才能通过返回的链接直接访问)。 ObjectMetadata objectMetadata = new ObjectMetadata(); objectMetadata.setContentType("image/jpg"); // 文件上传 ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content), objectMetadata); // 设置URL过期时间为1小时。 Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000); //返回url地址 String url = ossClient.generatePresignedUrl(bucketName, objectName, expiration).toString(); //关闭OSSClient。 ossClient.shutdown(); return url; } /** * 下载文件到本地 * @param endpoint OSS对外服务的访问域名 * @param accessKeyId accessKey账号 * @param accessKeySecret accessKey密码 * @param bucketName 桶名字 * @param objectName 完整文件名, 例如abc/efg/123.jpg * @param localFile 下载到本地文件目录 * @Author 千锋健哥 */ public static void downFile(String endpoint, String accessKeyId, String accessKeySecret, String bucketName, String objectName, String localFile) throws Exception { // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖,不存在则新建。 ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(localFile)); // 关闭OSSClient。 ossClient.shutdown(); } /** * 删除文件 * @param endpoint OSS对外服务的访问域名 * @param accessKeyId accessKey账号 * @param accessKeySecret accessKey密码 * @param bucketName 桶名字 * @param objectName 完整文件名, 例如abc/efg/123.jpg * @Author 千锋健哥 */ public static void deleteFile(String endpoint, String accessKeyId, String accessKeySecret, String bucketName, String objectName) { // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 删除文件。如需删除文件夹,请将ObjectName设置为对应的文件夹名称。如果文件夹非空,则需要将文件夹下的所有object删除后才能删除该文件夹。 ossClient.deleteObject(bucketName, objectName); // 关闭OSSClient。 ossClient.shutdown(); } }
4.3 上传文件案例
我们在Controller中实现文件上传。
package com.qianfeng.controller; import com.qianfeng.util.AliyunOSSUtil; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; /** * 文件管理接口 * 提供文件各种形式上传, 下载, 删除等操作 * @Author 千锋健哥 */ @RestController @RequestMapping("/file") public class FileManagerController { //OSS服务器访问域名 @Value("${aliyun.oss.endpoint}") private String endpoint; //子账户名 @Value("${aliyun.oss.accessKeyId}") private String accessKeyId; //子账户密码 @Value("${aliyun.oss.accessKeySecret}") private String accessKeySecret; //桶名字 @Value("${aliyun.oss.bucketName}") private String bucketName; /** * byte数组形式上传 * @param file * @Author 千锋健哥 */ @PostMapping("/upload1") public void upload(@RequestParam("file") MultipartFile file) throws Exception { AliyunOSSUtil.uploadByByteArrayFile(endpoint, accessKeyId, accessKeySecret, bucketName, file.getOriginalFilename(), file.getBytes()); } /** * 输入流形式上传 * @param file * @Author 千锋健哥 */ @PostMapping("/upload2") public void upload2(@RequestParam("file") MultipartFile file) throws Exception { AliyunOSSUtil.uploadByInputStreamFile(endpoint, accessKeyId, accessKeySecret, bucketName, file.getOriginalFilename(), file.getInputStream()); } }
4.4 上传图片并返回访问路径案例
在这个案例中健哥给大家展示了如何获取返回的访问路径。
/** * 上传图片并返回上传后的URL地址 * @param file * @Author 千锋健哥 */ @PostMapping("/upload3") public String upload3(@RequestParam("file") MultipartFile file) throws Exception { String url = AliyunOSSUtil.uploadImage(endpoint, accessKeyId, accessKeySecret, bucketName, file.getOriginalFilename(), file.getBytes()); System.out.println("===千锋健哥===" + url); return url; }
4.5 删除文件案例
这是删除上传后的文件案例。
/** * 删除文件 * @param objName 需要删除的对象名称 * @Author 千锋健哥 */ @DeleteMapping("/delete") public void deleteFile(String objName) { AliyunOSSUtil.deleteFile(endpoint, accessKeyId, accessKeySecret, bucketName, objName); }