云计算-使用Java访问S3 (Accessing S3 using Java)

        为了访问桶,我们使用AWS Java API。我们将使用API的2.0版本,但在撰写本文时,这是一个非常新的版本,因此您在互联网上找不到许多代码示例。版本1与版本2不兼容,不同的子版本之间也不兼容,因此我们必须非常小心地选择我们使用的API版本。在本单元中,我们将同时使用1.x版本和2.x版本。这是因为AWS上的大多数Java文档都是1.x版本。

       由于用于完成简单任务的类和接口很多。这是因为AWS并非用原生Java构建,因此每个数据结构都将有一个Java类/对象来提供对它的语言级访问。即使是对AWS接口的调用结果也将返回Java对象而不是简单的Java原始数据类型。习惯这一点需要一段时间。您还应该注意,所有类都记录在Java API文档中,因此当您遇到困难时,您需要学会如何导航文档。

        在本实验室剩余的部分,我们将操纵桶中的对象。在本单元中,我们不需要以编程方式操纵桶本身,而是我们将使用AWS控制台界面来操纵桶。但是,也有一整套Java API类和接口,用于在您的Java程序中操纵桶,您可以在自己的时间里尝试。

        我们使用Maven通过从Maven仓库加载所有适当的类来构建我们的Java程序。依赖关系和其他配置信息由pom.xml文件指定。

        我们可以添加与上周我们使用的pom.xml相关的S3依赖,并在本周用于S3。在后续的实验室会话中,我们将仅指定我们使用的亚马逊产品的相关API,您将需要将其插入类似于这个文件中的文件。请注意,此文件包含一些额外的指令,以便于您调试。这不是一个最小的pom.xml文件。例如,它包括shade插件,允许您在target目录运行jar文件。它还指定了UTF-8编码,以消除一些烦人的警告信息。

        第二个重要的“设置”活动是导入您在程序中使用的所有API类、接口、异常等。这些应该逐个导入,以帮助减小代码大小并帮助分析您的代码。AWS API是一个非常大的软件片段,因此这并不像听起来那么容易。您需要非常熟悉API文档,以找出应该从哪里导入类、接口和异常。在线会话中将显示一些这样做的技巧。本周我们需要的S3依赖项是:

<dependency><groupId>software.amazon.awssdk</groupId><artifactId>s3</artifactId><version>2.5.0</version>
</dependency>

        我们可以将此依赖项与上周的pom.xml文件一起添加,并在本周用于S3。

        我们已经知道在Cloud9中创建新的maven应用的命令,如下所示。

mvn -B archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=au.edu.scu.app -DartifactId=s3app

        附加文件:

  • pom.xml 使用ReadSpeaker docReader打开此文档 2.023 KB

从桶中读取对象

        有很多方法可以从桶中获取对象。我们可以将对象读入程序中的一个Java对象,我们可以将对象读入当前机器中的一个文件,我们可以将对象作为输入流读取,我们还可以使用多部分读取来读取大对象。这里我们将看一个技术,将对象读入本地文件。如果我们希望操纵对象,我们可以打开文件并使用标准的Java文件处理读取其数据。

        为了将对象读入本地文件系统,我们可以编写以下代码(完整程序)。这里我们打算从本实验室会话中较早创建的桶中读取index.html文件。您的桶名称将不同!

        我们需要导入以下类。

package au.edu.scu.app;import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
import software.amazon.awssdk.services.s3.model.S3Request;
import software.amazon.awssdk.services.s3.model.NoSuchKeyException;
import software.amazon.awssdk.core.sync.RequestBody;import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.FileSystems;

        然后我们编写以下代码,将"index.html"的内容读入名为"temp.txt"的本地文件(在应用内)。

public class App 
{public static S3Client s3;public static void main( String[] args ) throws IOException{String bucket = "pchakrab14-bucket-1";String key = "index.html";Region region = Region.US_EAST_1;s3 = S3Client.builder().region(region).build();Path path = FileSystems.getDefault().getPath("temp.txt");GetObjectRequest req =GetObjectRequest.builder().bucket(bucket).key(key).build();GetObjectResponse resp = s3.getObject(req, path);}
}

        您可能不习惯这样的代码。它使用静态构建方法创建程序内部使用的对象。当标准的new操作无法提供足够的信息来初始化这些对象时,通常需要这样做,因为它们依赖于从互联网或程序外部其他来源加载信息。

        关于这段代码的注解:

  • 代码构建了一个"S3Client"对象来访问s3产品。"S3Client"实际上是一个接口,所以实际的对象将是实现该接口的类。
  • "Path"对象定义了本地文件系统中的实际文件路径。在这个例子中,它是放置对象副本的文件的名称("index.html")。
  • 我们使用构建函数创建了一个"GetObjectRequest"对象,用来包含S3请求的细节。这里我们指定了区域、桶ID和对象名称(键)。
  • 我们通过在"S3Client"对象上调用"getObject()"方法来启动操作。它返回一个"GetObjectResponse"对象。注意这个函数有几个重载版本,这是将对象复制到指定路径的版本。
  • 这段代码中没有错误处理!大多数错误将作为异常被运行时系统捕获。例如,如果桶存在但我们指定了错误的键(对象ID),则会抛出"NoSuchKeyException"。
  • 错误处理很重要,既适用于实际程序中的恢复,也适用于调试代码。不总是容易看出错误将从哪里来。对于异常处理,我们只需要添加熟悉的try-catch语句,例如,要捕获"NoSuchKeyException",我们可以用以下代码替换上面的一些代码:
try {Region region = Region.US_EAST_1;s3 = S3Client.builder().region(region).build();Path path = FileSystems.getDefault().getPath("temp.txt");GetObjectRequest req =GetObjectRequest.builder().bucket(bucket).key(key).build();GetObjectResponse resp = s3.getObject(req, path);
} catch (NoSuchKeyException e) {System.err.println("That object does not exist.");
}

        请注意,我们已经在上面的第一个版本中包含了适当的导入语句:

import software.amazon.awssdk.services.s3.model.NoSuchKeyException;

        我们还可以通过捕获"S3Exception"异常来捕获所有S3异常,这是所有S3异常的基类。如下代码在调试时非常有用:

} catch (S3Exception e) { System.err.println(“S3 Exception: “+e.awsErrorDetails().errorMessage()); System.exit(-1); }

        其他问题可以通过查看"getObject()"函数调用返回的"GetObjectResponse"对象来确定。在这种情况下,如果成功将对象复制到文件中,对象将为null,所以只有异常才传递错误。

        我们需要使用上周使用的相同命令来编译和运行应用程序。

mvn packagejava -jar target/s3app1.0.jar

创建桶对象

        我们还可以在桶中放置对象。在这一节中,我们将在桶对象中放置数据存储在ByteBuffer对象中。

        首先,我们可以创建一些测试数据在ByteBuffer对象中,如下所示。添加这两个导入:

import java.nio.ByteBuffer;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;

        接下来的字符串将被写入我们将要创建的新对象内。

byte bytes[] = "this will be the contents of the object.".getBytes();
ByteBuffer data = ByteBuffer.wrap(bytes);

        此代码使用静态的"wrap()"函数创建一个新的"ByteBuffer"对象。之所以称之为‘wrap’,是因为它在字节数组周围创建了一个缓冲对象。字节数组仍然是数据的位置,而"ByteBuffer"对象允许使用标准接口访问数据。

        我们可以按照以下方式将对象存储在桶中。这里我们为对象的名称创建了一个新的键,以便它不与前一节中读取的对象发生冲突。

String writeKey = "data.tmp";   // 新对象名称
s3.putObject(PutObjectRequest.builder().bucket(bucket).key(writeKey).build(),
RequestBody.fromByteBuffer(data));

        关于这段代码有几个重要的事项需要注意:

  • 代码接续了前一节中定义的s3和bucket的代码。
  • 您需要将"PutObjectRequest"类导入程序。它以与前一节中使用的"GetObjectRequest"非常相似的方式使用构建器。
  • "RequestBody"类,它也在前一节中的get对象请求中使用过,有将"ByteBuffer"转换为适合S3的格式的方法。您应该注意,还有其他获取对象数据的方法,您可以在"RequestBody"文档中看到。

        另一个重要的问题可能已经出现在您的脑海中。我们如何能够在前一节中将桶设置为公共只读访问时写入桶。答案是您既拥有Cloud9 EC2实例又拥有桶,因此作为所有者,您对所有AWS服务都有写权限。EC2实例的开发环境在您每次启动时自动初始化。如果您使用另一个IDE或计算机,例如在PC上的NetBeans,您将不会被初始化,每次启动会话时都需要输入您的AWS凭据。"main()"内的完整代码看起来如下:

String bucket = "pchakrab14-bucket-1"; //您的桶名称
String readKey = "index.html"; //我们不需要这个键写入桶对象
try {Region region = Region.US_EAST_1;s3 = S3Client.builder().region(region).build();byte bytes[] = "this will be the contents of the object.".getBytes();ByteBuffer data = ByteBuffer.wrap(bytes);String writeKey = "data.tmp";   // 新对象名称s3.putObject(PutObjectRequest.builder().bucket(bucket).key(writeKey).build(), RequestBody.fromByteBuffer(data));
}
catch(NoSuchKeyException e) {System.err.println("That object does not exist.");
}

列出桶对象

        我们可以使用以下代码列出前一节中桶的所有对象。添加这些导入语句。

import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Response;
import software.amazon.awssdk.services.s3.model.S3Object;

        以下代码将手动将当前对象列表到终端。

ListObjectsV2Request listObjectsReqManual =ListObjectsV2Request.builder().bucket(bucket).maxKeys(1).build();boolean done = false; 
while (!done) {ListObjectsV2Response listObjResponse =s3.listObjectsV2(listObjectsReqManual);for (S3Object content : listObjResponse.contents()) {System.out.println(content.key());}if (listObjResponse.nextContinuationToken() == null) {done = true;}listObjectsReqManual =listObjectsReqManual.toBuilder().continuationToken(listObjResponse.nextContinuationToken()).build();
}

        这段代码比前几节中的代码要复杂得多。代码使用‘手动分页’,这意味着我们需要在循环遍历对象列表时添加我们自己的格式化数据。

        对于上述代码,您可以看到两个循环。有一个在done变量上的循环,还有一个处理由"listObjectV2()"方法返回的每个列表的for循环。需要两个循环的原因是"listObjectV2()"方法可能不会返回桶中的所有对象。最大数量由提供给构建器的"maxKeys()"调用控制。在这种情况下,我们将最大值设置为一个,所以for循环将只处理一个对象。while循环将一次迭代一个对象。

        有一个更强大的列表机制使用Iterable接口一次处理对象列表。这隐藏了上面的内部循环在一个迭代器中。以下代码执行此操作。它还为每个对象打印出不同格式的字符串,包括其大小。

import software.amazon.awssdk.services.s3.paginators.ListObjectsV2Iterable;ListObjectsV2Request listReq =ListObjectsV2Request.builder().bucket(bucket).maxKeys(1).build();ListObjectsV2Iterable listRes = s3.listObjectsV2Paginator(listReq);for (S3Object content : listRes.contents()) {System.out.println(" Key: " + content.key() + " size = "+ content.size());
}

        关于这段代码的一些要点:

  • 必须从"software.amazon.awssdk.services.s3.paginators"包中导入"ListObjectsV2Iterable"类。
  • 这段代码中的第一条语句与上面的手动分页代码中的第一条语句完全相同。第二条语句将列表对象转换为可迭代列表。
  • for循环使用标准的Java for-each处理。

        您将熟悉带有Iterable接口的对象,因为您之前的Java编程经验中有很多用于处理可迭代对象的实用函数,许多这些函数允许将通用函数应用到每个元素上,例如使用lambda表达式。例如,我们可以使用以下方式处理上述可迭代对象列表作为流:

listRes.contents().stream().forEach(content -> System.out.println(" Key: " +content.key() +" size = " +content.size()));

        这里的"stream()"方法返回由可迭代对象列表组成的流。"forEach()"方法然后将lambda表达式映射到流的每个元素。

删除桶对象

        要删除对象,我们使用与之前的请求非常相似的方式使用"DeleteObjectRequest"。以下代码将删除我们之前创建的对象。

import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;DeleteObjectRequest delRequest = DeleteObjectRequest.builder().bucket(bucket).key(deleteKey).build();
s3.deleteObject(delRequest);

如前所述,请注意以下事项:

  • 代码接续了前一节中定义的s3、deleteKey和bucket的代码。
  • 您需要将"DeleteObjectRequest"类导入程序。它以与之前使用的"GetObjectRequest"非常相似的方式使用构建器。
  • 删除对象时没有确认。如果对象存在,S3将继续删除对象。如果您想在程序中确认删除,您将需要自己实现代码。

故障排除

        在运行S3应用程序后,您可能在终端看到以下错误消息。

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

        您可以将以下依赖项添加到您的pom.xml中以避免这些错误消息。

<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-simple</artifactId><version>1.7.21</version>
</dependency>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

amis 文件上传 大文件分块上传

amis 图片/文件上传组件 receiver&#xff1a;参数配置为上传接口。 {"type": "input-image", // "type": "input-file","label": "照片","name": "url", "imageClassName": &qu…

VUE3视频播放器 videojs-player/vue

简介 官网&#xff1a; https://gitcode.com/surmon-china/videojs-player/overviewhttps://github.com/surmon-china/videojs-player?tabreadme-ov-file video-player是一个基于video.js的视频播放器组件&#xff0c;它提供了丰富的功能&#xff0c;包括视频播放、暂停、快…

CentOS 7 socat命令端口转发

场景 开发排查问题需配置远程调试,但配置调试的服务器不支持外网访问,于是就考虑到用端口转发的方式让开发进行远程调试,转发工具比如有:rinetd等等,意外看到使用socat做转发更简单方便,下面就记录一下 命令简介 socat 是一个功能强大的网络工具,可以在两个连接的数据…

B2123 字符串 p 型编码

字符串 p 型编码 题目描述 给定一个完全由数字字符&#xff08;‘0’,‘1’,‘2’,…,‘9’&#xff09;构成的字符串 str &#xff0c;请写出 str 的 p 型编码串。例如&#xff1a;字符串 122344111 可被描述为 1个1、2个2、1个3、2个4、3个1 &#xff0c;因此我们说1223441…

JMeter学习笔记二

面试题&#xff1a; 1.做接口测试时&#xff0c;你是怎么做的数据校验(返回值验证)&#xff1f;一般你会验证哪些数据&#xff1f; 校验code 200&#xff08;说明后端接到了你的请求&#xff0c;并且给了应答&#xff09; 返回信息 sucess 2.有1w个用户名密码需要登录&#xff…

AI学习指南数学工具篇-梯度下降在机器学习中的应用

AI学习指南数学工具篇-梯度下降在机器学习中的应用 线性回归模型中的梯度下降 线性回归是一种用于建立预测模型的基本统计方法。在线性回归中&#xff0c;我们试图通过输入特征的线性组合来预测输出变量的值。梯度下降是一种优化算法&#xff0c;在线性回归模型中&#xff0c…

微信小程序源码-基于Java后端的网上商城系统毕业设计(附源码+演示录像+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;微信小程序毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设…

题解 P1150

题解 P1150 因为k个烟蒂1根烟1个烟蒂 所以k-1个烟蒂1根烟 注意减掉最后一根烟的烟蒂 (因这题并没有借烟蒂换烟再还回这一说) 此解法为小学4~6年级水平 #include <bits/stdc.h>using namespace std;int main(){int n,k;cin>>n>>k;cout<<n(n-1)/(k-…

代码随想录——找树左下角的值(Leetcode513)

题目链接 层序遍历 思路&#xff1a;使用层序遍历&#xff0c;记录每一行 i 0 的元素&#xff0c;就可以找到树左下角的值 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}*…

北核论文完美复现:自适应t分布与动态边界策略改进的算术优化算法

声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 目录 原始算术优化算法 改进点1&#xff1a;引入…

【Linux】Ubuntu系统挂载NAS文件夹

测试系统&#xff1a;Ubuntu24.02 1. 安装必要的软件包 sudo apt update sudo apt install cifs-utils 2. 创建挂载点 sudo mkdir -p /mnt/nas 3. 获取当前用户的 UID 和 GID id -u id -g 4. 挂载&#xff1a;设置用户名/密码/nas地址 sudo mount -t cifs -o username,…

【网络】socket套接字结合IO多路复用

引言 在多线程编程中&#xff0c;I/O 多路复用&#xff08;如 select、poll 或 epoll&#xff09;可以与多线程结合使用&#xff0c;以提高系统的并发处理能力和效率。结合多线程和 I/O 多路复用&#xff0c;可以实现高性能的网络服务器和客户端。以下是一些常见的多线程和 I/…

vue+css解决图片变形问题(flex-shrink: 0)

解决前 给图片添加 flex-shrink: 0;即可解决图片变形问题

基于springboot+vue的致远汽车租赁系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

东方通TongWeb结合Spring-Boot使用

一、概述 信创需要; 原状:原来的服务使用springboot框架,自带的web容器是tomcat,打成jar包启动; 需求:使用东方通tongweb来替换tomcat容器; 二、替换步骤 2.1 准备 获取到TongWeb7.0.E.6_P7嵌入版 这个文件,文件内容有相关对应的依赖包,可以根据需要来安装到本地…

上5个B端系统的设计规范,让你的开发比着葫芦画瓢。

B端系统设计规范在企业级系统开发中起着重要的作用&#xff0c;具体包括以下几个方面&#xff1a; 统一风格和布局&#xff1a;设计规范能够统一系统的风格和布局&#xff0c;使不同功能模块的界面看起来一致&#xff0c;提升用户的使用体验和学习成本。通过统一的设计规范&am…

Day42 最后一块石头的重量Ⅱ + 目标和 + 一和零

1049 最后一块石头的重量Ⅱ 题目链接&#xff1a;1049.最后一块石头的重量Ⅱ 有一堆石头&#xff0c;用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合&#xff0c;从中选出任意两块石头&#xff0c;然后将它们一起粉碎。假设石头的重量分别为 x 和…

力扣 5. 最长回文子串 python AC

动态规划 class Solution:def longestPalindrome(self, s):size len(s)maxl 1start 0dp [[False] * size for _ in range(size)]for i in range(size):dp[i][i] Truefor L in range(2, size 1):for i in range(size):j L i - 1if j > size:breakif s[i] s[j]:if L…

AI大模型领域新闻跟踪

杨值麟 月之暗面杨植麟&#xff1a;大模型开发是“承包森林”月之暗面集结最强创投&#xff0c;“清华师姐”是最强“助攻”月之暗面杨植麟&#xff1a;互联网研发是“种树”&#xff0c;大模型研发是“承包森林”月之暗面杨植麟复盘大模型创业这一年&#xff1a;向延绵而未知…

Web课外练习9

<!DOCTYPE html> <html> <head><meta charset"utf-8"><title>邮购商品业务</title><!-- 引入vue.js --><script src"./js/vue.global.js" type"text/javascript"></script><link rel&…