阿里云对象存储Java-SDK实战
本文从本人博客搬运,原文格式更加美观,可以移步原文阅读:阿里云对象存储Java-SDK实战
目前项目中要保存上传的文件,很多时候都会用到对象存储。本文介绍阿里云对象存储Java-SDK在实际开发中的基本用法
基本使用
1.开通OSS服务
首先要开通阿里云OSS服务,登录阿里云,找到对象存储OSS
点击立即开通
2.创建子AccessKey
接着我们要用java代码完成将文件上传到阿里云OSS的功能。调用阿里云的服务接口需要AccessKey
,默认的AccessKey
是全局的,可以登录阿里云,并且权限很大,不推荐在程序中直接使用。我们可以新建一个子AccessKey
,专门用于编程中使用。进入AccessKey
管理,新建一个用于编程访问的子AccessKey
,并给其授予管理对象存储的权限
完成后,记得保存子AccessKey的Id与Secret,后续编程访问的时候会用到
3.创建Bucket
一个Bucket
相当于一个文件仓库,可以用来存放我们上传的文件。我们可以在管理控制台创建Bucket
4.编程访问
首先引入OSS的SDK依赖
<dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.8.0</version>
</dependency>
然后编写测试代码,上传一个本地文件,过程如下:
- 利用
endpoint
、accessKeyId
、accessKeySecret
创建OSS
对象 - 利用
OSS
对象将文件流写入到之前创建的Bucket
中 - 关闭
OSS
对象
@Test
public void testUploadFile() throws FileNotFoundException {// Endpoint以杭州为例,其它Region请按实际情况填写。String endpoint = "oss-cn-hangzhou.aliyuncs.com";// 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建。String accessKeyId = "用之前创建的子AccessKey";String accessKeySecret = "用之前创建的子AccessKey";// 创建OSSClient实例。OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);// 上传文件流。InputStream inputStream = new FileInputStream("C:\\Users\\baobao\\Desktop\\guojia.jpg");// 将文件写入Bucket,参数1:Bucket名称 参数2:上传后的文件名 参数3:文件输入流ossClient.putObject("gulimall-baobao", "guojia.jpg", inputStream);// 关闭OSSClient。ossClient.shutdown();
}
代码运行成功后即可看到上传的文件
使用SpringCloud Alibaba快捷操作
之前我们是自己创建OSS对象来进行操作,实际上还可以整合SpringCloud Alibaba来更加方便地使用OSS。打开官方文档,找到OSS相关
在SpringBoot项目中引入OSS的starter
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alicloud-oss</artifactId>
</dependency>
可以看到starter已经帮我们引入了OSS的基础SDK
然后在yml配置文件中配置endpoint
、accessKeyId
、accessKeySecret
server:port: 30000
spring:cloud:alicloud:oss:endpoint: oss-cn-hangzhou.aliyuncs.comaccess-key: ...secret-key: ...
在测试代码中无需创建ossClient,只需要将其注入进来即可使用
@RunWith(SpringRunner.class)
@SpringBootTest
public class GulimallThirdpartyApplicationTests {// 注入ossClient@Autowiredprivate OSS ossClient;@Testpublic void testUploadFile() throws FileNotFoundException {// 上传文件流。InputStream inputStream = new FileInputStream("C:\\Users\\baobao\\Desktop\\guojia.jpg");ossClient.putObject("gulimall-baobao", "guojia222.jpg", inputStream);// 关闭OSSClientossClient.shutdown();}
}
前端直传
如果我们用之前的方式上传文件到OSS,那么后端需要先接收前端表单上传的文件,然后再通过SDK将文件上传到OSS。但是实际开发中不推荐这么做,因为这种方式使得文件流先从客户端到后端应用服务器,然后再由服务器转给OSS,相当于多了1次中转,十分浪费服务器带宽,当很多用户都在上传的时候对后端应用服务器的带宽以及处理压力很大
我们可以采取的优化方式是:在浏览器提交上传Policy
请求给服务器,服务器返回上传Policy
和签名,将上传地址等重要信息告诉浏览器,这样就可以由浏览器在客户端直接完成上传到oss的操作,分担了服务器压力
新建一个OssController,编写生成Policy
和前面的方法,参考阿里云官方SDK文档
@RestController
public class OssController {// 注入ossClient@Autowiredprivate OSS ossClient;// 从配置文件中获取accessKey、endpoint等必要信息@Value("${spring.cloud.alicloud.oss.endpoint}")private String endpoint;@Value("${spring.cloud.alicloud.access-key}")private String accessKey;@Value("${spring.cloud.alicloud.secret-key}")private String secretKey;@Value("${spring.cloud.alicloud.bucket-name}")private String bucketName;@RequestMapping("oss/policy")public Map<String, String> policy() {// 用户上传文件时指定的前缀,指定当前日期String date = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDate.now());String dir = date + "/";// host的格式为 bucketname.endpointString host = "https://" + bucketName + "." + endpoint;try {long expireTime = 30;long expireEndTime = System.currentTimeMillis() + expireTime * 1000;Date expiration = new Date(expireEndTime);// PostObject请求最大可支持的文件大小为5 GB,即CONTENT_LENGTH_RANGE为5*1024*1024*1024。PolicyConditions policyConds = new PolicyConditions();policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);byte[] binaryData = postPolicy.getBytes("utf-8");String encodedPolicy = BinaryUtil.toBase64String(binaryData);String postSignature = ossClient.calculatePostSignature(postPolicy);Map<String, String> respMap = new LinkedHashMap<>();respMap.put("accessid", accessKey);respMap.put("policy", encodedPolicy);respMap.put("signature", postSignature);respMap.put("dir", dir);respMap.put("host", host);respMap.put("expire", String.valueOf(expireEndTime / 1000));// respMap.put("expire", formatISO8601Date(expiration));return respMap;} catch (Exception e) {// Assert.fail(e.getMessage());System.out.println(e.getMessage());return null;} finally {ossClient.shutdown();}}
}
然后注意由于我们自定义了bucketName也从yml配置文件中取,所以要在yml中定义
server:port: 30000
spring:cloud:alicloud:oss:endpoint: oss-cn-hangzhou.aliyuncs.comaccess-key: ...secret-key: ...bucket-name: gulimall-baobao # 配置bucket-name
测试访问接口,可以获取相关参数。前端拿到这些参数后,可以利用accessId
、policy
、signature
将文件直传到host
+dir
的目录中
实际开发中建议合理规划好文件保存的
dir
目录,可以用日期时间划分,也可以根据实际情况用不同的业务模块划分
临时URL访问文件
之前我们对Bucket
的读写权限设置为公共读,这样只要获取了文件的url,就可以在浏览器随意访问了,安全性不好
一般建议是将Bucket
的读写权限设置为私有,此时再通过文件url访问将会提示没有权限
需要在url上附带一些参数,用这个附带参数的临时url才能访问到文件,而临时url过期后就无法再访问了。我们进入oss控制台,点击文件的详情就会显示临时url
分析一下这个url的结构
https://gulimall-baobao.oss-cn-hangzhou.aliyuncs.com/guojia.jpg?Expires=1616766718&OSSAccessKeyId=TMP.3KjvuWJovuqLjNppoo3D3jvDbZFbrfovBR39zhHkdmzrm6M9mdwJAkbc1Ffdhn77nyVWTi2PATz97t5zSKr2TDhoKiE1SY&Signature=jAVkArqRd8K2jFswLy9%2BzH62Emk%3D
可以看出其携带了3个参数:
Expires
:临时url的过期时间,默认5分钟OSSAccessKeyId
:临时的accessKeySignature
:签名
我们每点击一次详情,都会生成一个新的临时url,过期时间为点击后的5分钟,临时的accessKey都相同,但是签名不同。可以推测生成签名的参数中有过期时间
在我们自己的应用中,公共读的方式下,后端数据库只要保存文件上传后的url即可,前端需要展示图片的时候只要向后端请求获取图片url并交给图片组件即可。然而改成私有以后,前端如何向后端请求临时url并显示图片文件呢?此时后端接收到前端访问图片的请求,并获取数据库中图片的url后,不能直接返回给前端,需要先解析出图片文件在Bucket
中的路径,然后根据bucketName
、临时url超时时间、要访问文件在Bucket
中的路径这3个参数生成一个临时的url返回给前端
@Component
public class AliyunOssService {// Endpoint以杭州为例,其它Region请按实际情况填写。String endpoint = "oss-cn-hangzhou.aliyuncs.com";// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。String accessKeyId = "...";String accessKeySecret = "...";String bucketName = "gulimall-baobao";// objectName即文件在Bucket中的路径public String getTempUrl(String objectName){// 创建OSSClient实例。OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);// 设置URL过期时间为1小时。Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);// 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。其中objectName即文件在Bucket中的路径URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);// 关闭OSSClient。ossClient.shutdown();return url.toString();}
}
@SpringBootTest
class AliyunOssDemoApplicationTests {@Autowiredprivate AliyunOssService aliyunOssService;@Testvoid contextLoads() {String tempUrl = aliyunOssService.getTempUrl("guojia.jpg");System.out.println(tempUrl);}
}
测试生成的临时url如下,生成的规则是http://bucketName.endPoint/要访问的文件在Bucket中的路径
,后面携带超时时间、临时的accessKey、签名等参数
如果要访问的文件位于Bucket
中的某个文件夹下,获取临时url时传入的文件路径参数只需要带上文件夹即可,注意最外层文件夹前面不能带/
阿里云对象存储Java-SDK实战相关推荐
- 美团 java_GitHub - meituan/mssapi_java: 美团云对象存储 Java SDK
MSS(Meituan Storage Service) SDK for Java This is MSS SDK for Java. Introduction MSS服务介绍 美团云存储服务(Mei ...
- 阿里云 对象存储java实现OSS文件上传及获取URL
本人已尝试上传成功 maven加载的jar包 pom配置 <dependency><groupId>com.aliyun.oss</groupId><arti ...
- 谷粒学苑项目实战(九):实现阿里云对象存储OSS功能
目录 一.开通阿里云对象存储OSS 二.创建bucket 三.创建操作阿里云OSS许可证 四.用代码实现头像上传功能 五.引入相关依赖 六.创建properties配置文件 七.创建主启动类 八.启动 ...
- 阿里云对象存储OSS与文件存储NAS的区别
一.简介 应用场景:选择一款存储产品,面向文档数据的存取,不会涉及到数据处理. 产品选型主要从OSS和NAS中选择一款,满足文档存储的需求. 二.NAS优缺点 NAS 是一种采用直接与网络介质相连的特 ...
- 阿里云对象存储OSS(Object Storage Service)
文章目录 简介 endpoint:阿里云服务部署的地区位置 见解 开发步骤 配置文件 utils层(读取全局配置文件并赋值给类变量) service层 impl(基于oss驱动sdk实现类) cont ...
- 阿里云对象存储服务OSS前后联调
阿里云对象存储服务OSS前后联调 1.为什么要引入阿里云对象存储服务(OSS)?有什么好处? 1.1.什么是对象存储OSS 1.2.OSS工作原理 2.阿里云对象存储-普通上传方式 2.1.时序图 2 ...
- 云储存-阿里云对象存储
云存储-阿里云对象存储 一.概念 单体项目与分布式项目对比 上传方式 二.开通 注册并实名 三.开通对象存储,并创建新Bucket 3.1 创建Bucket 一个项目对应一个bucket 3.2 SD ...
- 阿里云对象存储OSS竟如此简单
1.1:什么是阿里云的OSS 阿里云对象存储服务(Object Storage Service,简称OSS),是阿里云对外提供的海量.安全.低成本.高可靠的云存储服务.您可以通过本文档提供的简单的RE ...
- 阿里云对象存储OSS支持版本管理特性
2019独角兽企业重金招聘Python工程师标准>>> 阿里云对象存储OSS现已经全面支持"对象版本管理"特性.该功能适用于所有的存储类型以及区域.当Bucket ...
最新文章
- 最小树形图及其生产方法
- 图解:消息传输的架构模式
- 新的机器学习特性包含Python
- java中Map的用法(HaspMap用法)
- linux如何查看所有的用户(user)、用户组(group)、密码(password/passwd)
- UVA 10453—— Make Palindrome
- 最新!复旦大学邱锡鹏教授等「Transformers全面综述」论文
- 小米组织架构再调整:手机部成立参谋部 朱磊出任参谋长
- was环境通过HTTPS访问其他域名报错 CWPKI0022E: SSL 握手故障:已从目标主机:端口“。。。...
- ZH奶酪:PHP中添加HTML代码的三种方法
- [大数据 ]Apache大数据项目目录
- 微信公众号网页开发,登录授权和微信支付
- 固态激光雷达:扫地机器人的旋转激光雷达的三角测距示意原理与分析
- 5G牌照发放 ,手机产业将迎来第二春
- 2012-2013年薪水涨幅最高的十五个IT职位
- 关于华为手机P20pro装包时总提示冲突问题
- 如何用python打印三角阵列_如何打印完整的NumPy阵列?
- 一文看懂 webpack 的所有 source map !
- 在 Mac 上将 PDF 转换为 Word 的 5 种简单方法
- 一些牛人榜样,多看看他们写的东西(后续整理牛人的blog等)
热门文章
- The stash entry is kept in case you need it again.
- gradle project sync failed.please fix your project and try again-Android Studio3.1.2运行出错
- Nginx stream 配置代理(Nginx TCP/UDP 负载均衡)
- 华为煤矿军团首登央视 | 发布会金句爆棚
- 蓝色插画风新媒体运营转正汇报PPT模板
- java itextpdf 5 基础知识
- 如何推广企业微信号?企业进行公众号的推广有哪些方法?
- Android手绘涂鸦PaintView
- xcode证书及打包
- Laragon实现快速创建ThinkPHP项目