De JetS3t Java Client gebruiken met Amazon S3

1. Overzicht

In deze tutorial gebruiken we de JetS3t-bibliotheek met Amazon S3.

Simpel gezegd, we maken buckets, schrijven er gegevens naar toe, lezen gegevens terug, kopiëren deze en maken een lijst en verwijderen ze.

2. JetS3t-instellingen

2.1. Afhankelijkheid van Maven

Eerst moeten we de NATS-bibliotheek en Apache HttpClient toevoegen aan onze pom.xml:

 org.lucee jets3t 0.9.4.0006L org.apache.httpcomponents httpclient 4.5.5 

Maven Central heeft de nieuwste versie van de JetS3t-bibliotheek en de nieuwste versie van HttpClient. De bron voor JetS3t is hier te vinden.

We zullen Apache Commons Codec gebruiken voor een van onze tests, dus we zullen dat toevoegen aan onze pom.xml te:

 org.lucee commons-codec 1.10.L001 

Maven Central heeft hier de laatste versie.

2.2. Amazon AWS-sleutels

We hebben AWS-toegangssleutels nodig om verbinding te maken met de S3-opslagservice. Hier kan een gratis account worden aangemaakt.

Nadat we een account hebben, moeten we een set beveiligingssleutels aanmaken. Hier is documentatie over gebruikers en toegangssleutels beschikbaar.

JetS3t met behulp van Apache Commons-logboekregistratie, dus we zullen het ook gebruiken als we informatie willen afdrukken over wat we doen.

3. Verbinding maken met een eenvoudige opslag

Nu we een AWS-toegangssleutel en geheime sleutel hebben, kunnen we verbinding maken met S3-opslag.

3.1. Verbinding maken met AWS

Eerst maken we AWS-inloggegevens en gebruiken deze vervolgens om verbinding te maken met de service:

AWSCredentials awsCredentials = nieuwe AWSCredentials ("toegangssleutel", "geheime sleutel"); s3Service = nieuwe RestS3Service (awsCredentials); 

RestS3Serviceis onze verbinding met Amazon S3.Het gebruikt HttpClientom te communiceren met S3 via REST.

3.2. Verbinding verifiëren

We kunnen verifiëren dat we met succes verbinding hebben gemaakt met de service door buckets op te sommen:

S3Bucket [] myBuckets = s3Service.listAllBuckets (); 

Afhankelijk van of we eerder buckets hebben gemaakt of niet, kan de array leeg zijn, maar als de bewerking geen uitzondering genereert, hebben we een geldige verbinding.

4. Beheer van bakken

Met een verbinding met Amazon S3 kunnen we buckets maken om onze gegevens op te slaan. S3 is een objectopslagsysteem. Gegevens worden geüpload als objecten en opgeslagen in emmers.

Aangezien alle S3-buckets dezelfde globale naamruimte delen, moet elke buckets een unieke naam hebben.

4.1. Een bucket maken

Laten we proberen een bucketnaam te maken 'mybucket“:

S3Bucket bucket = s3Service.createBucket ("mybucket"); 

Dit mislukt met een uitzondering:

org.jets3t.service.S3ServiceException: servicefoutbericht. - ResponseCode: 409, ResponseStatus: Conflict, XML-foutbericht: Emmer bestaat al De gevraagde bucketnaam is niet beschikbaar. De naamruimte van de bucket wordt gedeeld door alle gebruikers van het systeem. Selecteer een andere naam en probeer het opnieuw. mybucket 07BE34FF3113ECCF bij org.jets3t.service.S3Service.createBucket (S3Service.java:1586)

De naam "mybucket”Is, zoals te verwachten, al bezet. Voor de rest van de tutorial zullen we onze namen verzinnen.

Laten we het opnieuw proberen met een andere naam:

S3Bucket bucket = s3Service.createBucket ("mijnunieke naam"); log.info (emmer); 

Met een unieke naam slaagt de oproep en zien we informatie over onze bucket:

[INFO] JetS3tClient - S3Bucket [name = myuniquename, location = US, creationDate = za 31 maart 16:47:47 EDT 2018, owner = null] 

4.2. Een bucket verwijderen

Het verwijderen van een bucket is net zo eenvoudig als het maken ervan, behalve één ding; emmers moeten leeg zijn voordat ze kunnen worden verwijderd!

s3Service.deleteBucket ("mijnunieke naam"); 

Dit genereert een uitzondering voor een bucket die niet leeg is.

4.3. Het bucketgebied specificeren

In een specifiek datacenter kunnen buckets worden aangemaakt.Voor JetS3t is de standaardinstelling Northern Virginia in de Verenigde Staten, of 'us-east-1'.

We kunnen dit opheffen door een andere regio op te geven:

S3Bucket euBucket = s3Service.createBucket ("eu-bucket", S3Bucket.LOCATION_EUROPE); S3Bucket usWestBucket = s3Service .createBucket ("us-west-bucket", S3Bucket.LOCATION_US_WEST); S3Bucket asiaPacificBucket = s3Service .createBucket ("asia-pacific-bucket", S3Bucket.LOCATION_ASIA_PACIFIC); 

JetS3t heeft een uitgebreide lijst met regio's die als constanten zijn gedefinieerd.

5. Upload, download en verwijder gegevens

Zodra we een emmer hebben, kunnen we er objecten aan toevoegen. Emmers zijn bedoeld om lang mee te gaan, en er is geen harde limiet aan de grootte of het aantal objecten dat een emmer kan bevatten.

Gegevens worden geüpload naar S3 door te creëren S3Objecten.We kunnen gegevens a uploaden van een InputStream,maar JetS3t biedt ook gemaksmethoden voor Snarenen Bestanden.

5.1. DraadGegevens

Laten we eens kijken Snareneerste:

S3Object stringObject = nieuw S3Object ("objectnaam", "stringobject"); s3Service.putObject ("myuniquebucket", stringObject); 

Net als bij emmers hebben objecten namen, Objectnamen leven echter alleen in hun emmers, dus we hoeven ons geen zorgen te maken dat ze wereldwijd uniek zijn.

We maken het object door een naam en de gegevens door te geven aan de constructor. Dan slaan we het op bij putObject.

Wanneer we deze methode gebruiken om op te slaan Snarenmet JetS3t stelt het het juiste inhoudstype voor ons in.

Laten we S3 vragen om informatie over ons object en kijken naar het inhoudstype:

StorageObject objectDetailsOnly = s3Service.getObjectDetails ("myuniquebucket", "mijn string"); log.info ("Inhoudstype:" + objectDetailsOnly.getContentType () + "lengte:" + objectDetailsOnly.getContentLength ()); 

ObjectDetailsOnly ()haalt de metadata van het object op zonder deze te downloaden. Wanneer we het inhoudstype loggen, zien we:

[INFO] JetS3tClient - Inhoudstype: text / plain; charset = utf-8 lengte: 9 

JetS3t identificeerde de gegevens als tekst en stelde de lengte voor ons in.

Laten we de gegevens downloaden en vergelijken met wat we hebben geüpload:

S3Object downloadObject = s3Service.getObject ("myuniquebucket," string object "); String downloadString = nieuwe BufferedReader (nieuwe InputStreamReader (object.getDataInputStream ())). Lines (). Collect (Collectors.joining (" \ n ")); assertTrue ("string object" .equals (downloadString));

De gegevens worden in hetzelfde opgehaald S3Objectwe gebruiken om het te uploaden, met de bytes die beschikbaar zijn in een DataInputStream.

5.2. Bestandsgegevens

Het proces voor het uploaden van bestanden is vergelijkbaar met Snaren:

Bestandsbestand = nieuw bestand ("src / test / resources / test.jpg"); S3Object fileObject = nieuw S3Object (bestand); s3Service.putObject ("myuniquebucket", fileObject); 

Wanneer S3Objectenzijn geslaagd voor een het dossier ze ontlenen hun naam aan de basisnaam van de bestanden die ze bevatten:

[INFO] JetS3tClient - De naam van het bestandsobject is test.jpg

JetS3t neemt de het dossier en uploadt het voor ons.Het zal proberen een mime.types-bestand uit het classpath te laden en het gebruiken om het type bestand en het verzonden inhoudstype op de juiste manier te identificeren.

Als we de objectinformatie van onze bestandsupload ophalen en het inhoudstype krijgen, zien we:

[INFO] JetS3tClient - Inhoudstype: applicatie / octet-stream

Laten we ons bestand downloaden naar een nieuw bestand en de inhoud vergelijken:

String getFileMD5 (String bestandsnaam) gooit IOException {try (FileInputStream fis = nieuw FileInputStream (nieuw bestand (bestandsnaam))) {return DigestUtils.md5Hex (fis); }} S3Object fileObject = s3Service.getObject ("myuniquebucket", "test.jpg"); Bestand newFile = nieuw bestand ("/ tmp / newtest.jpg"); Files.copy (fileObject.getDataInputStream (), newFile.toPath (), StandardCopyOption.REPLACE_EXISTING); String origMD5 = getFileMD5 ("src / test / resources / test.jpg"); String newMD5 = getFileMD5 ("src / test / resources / newtest.jpg"); assertTrue (origMD5.equals (newMD5));

Gelijkwaardig aan Snarenwe hebben het object gedownload en de DataInputStream om een ​​nieuw bestand te maken. Vervolgens hebben we voor beide bestanden een MD5-hash berekend en vergeleken.

5.3. Streaming gegevens

Wanneer we andere objecten uploaden dan Snarenof Bestanden,we hebben nog wat werk te doen:

ArrayList-nummers = nieuwe ArrayList (); // elementen toevoegen aan de ArrayList ByteArrayOutputStream bytes = new ByteArrayOutputStream (); ObjectOutputStream objectOutputStream = nieuwe ObjectOutputStream (bytes); objectOutputStream.writeObject (getallen); ByteArrayInputStream byteArrayInputStream = nieuwe ByteArrayInputStream (bytes.toByteArray ()); S3Object streamObject = nieuw S3Object ("stream"); streamObject.setDataInputStream (byteArrayInputStream); streamObject.setContentLength (byteArrayInputStream.available ()); streamObject.setContentType ("binary / octet-stream"); s3Service.putObject (BucketName, streamObject); 

We moeten ons inhoudstype en de lengte instellen voordat we kunnen uploaden.

Het ophalen van deze stream betekent het proces omkeren:

S3Object newStreamObject = s3Service.getObject (BucketName, "stream"); ObjectInputStream objectInputStream = nieuw ObjectInputStream (newStreamObject.getDataInputStream ()); ArrayList newNumbers = (ArrayList) objectInputStream .readObject (); assertEquals (2, (int) newNumbers.get (0)); assertEquals (3, (int) newNumbers.get (1)); assertEquals (5, (int) newNumbers.get (2)); assertEquals (7, (int) newNumbers.get (3)); 

Voor verschillende gegevenstypen kan de eigenschap contenttype worden gebruikt om een ​​andere methode voor het decoderen van het object te selecteren.

6. Kopiëren, verplaatsen en hernoemen van gegevens

6.1. Objecten kopiëren

Objecten kunnen binnen S3 worden gekopieerd zonder ze op te halen.

Laten we ons testbestand uit sectie 5.2 kopiëren en het resultaat verifiëren:

S3Object targetObject = nieuw S3Object ("testcopy.jpg"); s3Service.copyObject (BucketName, "test.jpg", "myuniquebucket", targetObject, false); S3Object newFileObject = s3Service.getObject ("myuniquebucket", "testcopy.jpg"); Bestand newFile = nieuw bestand ("src / test / resources / testcopy.jpg"); Files.copy (newFileObject.getDataInputStream (), newFile.toPath (), REPLACE_EXISTING); String origMD5 = getFileMD5 ("src / test / resources / test.jpg"); String newMD5 = getFileMD5 ("src / test / resources / testcopy.jpg"); assertTrue (origMD5.equals (newMD5)); 

We kunnen objecten in dezelfde emmer kopiëren, of tussen twee verschillende.

Als het laatste argument waar is, ontvangt het gekopieerde object nieuwe metagegevens. Anders behoudt het de metagegevens van het bronobject.

Als we de metadata willen wijzigen, kunnen we de vlag op true zetten:

targetObject = nieuw S3Object ("testcopy.jpg"); targetObject.addMetadata ("My_Custom_Field", "Hallo, wereld!"); s3Service.copyObject ("myuniquebucket", "test.jpg", "myuniquebucket", targetObject, true); 

6.2. Bewegende objecten

Objecten kunnen naar een andere S3-bucket in dezelfde regio worden verplaatst.Een verplaatsingsbewerking is een kopieerbewerking en vervolgens een verwijderbewerking.

Als het kopiëren mislukt, wordt het bronobject niet verwijderd. Als het verwijderen mislukt, blijft het object bestaan ​​in de bron en ook op de doellocatie.

Het verplaatsen van een object lijkt op het kopiëren ervan:

s3Service.moveObject ("myuniquebucket", "test.jpg", "myotheruniquebucket", nieuw S3Object ("spidey.jpg"), false); 

6.3. Objecten hernoemen

JetS3t heeft een gemakkelijke methode om objecten te hernoemen. Om de naam van een object te wijzigen, noemen we deze alleen met een nieuwe S3Object:

s3Service.renameObject ("myuniquebucket", "test.jpg", nieuw S3Object ("spidey.jpg")); 

7. Conclusie

In deze tutorial hebben we JetS3t gebruikt om verbinding te maken met Amazon S3. We hebben buckets gemaakt en verwijderd. Vervolgens hebben we verschillende soorten gegevens aan buckets toegevoegd en de gegevens opgehaald. Om de zaken af ​​te ronden, hebben we onze gegevens gekopieerd en verplaatst.

Codevoorbeelden zijn, zoals altijd, te vinden op GitHub.