Create Amazon AWS S3 Bucket in Java

In this short blog post I am going to share with you how to create a new Amazon AWS S3 bucket in Java and how to set permissions on it so that any user can read files from it but only you, the owner will have write access.

You can use the code below with any type of Java project but since I am building RESTful Web services for mobile applications I will first create a new JAX-RS Web App and then will add to it support for Amazon AWS S3 Java SDK.

Create JAX-RS Web App with Maven

Follow this example to quickly create a very simple JAX-RS Web app which you can use for your RESTful Web Services API as well.

Amazon AWS S3 Bucket POM.XML Dependency

Now, when we have created a simple JAX-RS Web Application we need to add Amazon AWS library dependency to our pom.xml file. Below is my complete pom.xml file with the Amazon AWS library dependency added.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.appsdeveloperblog.ws</groupId>
    <artifactId>AmazonExamples</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>AmazonExamples Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.bundles/jaxrs-ri -->
        <dependency>
            <groupId>org.glassfish.jersey.bundles</groupId>
            <artifactId>jaxrs-ri</artifactId>
            <version>2.25</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-moxy -->
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-moxy</artifactId>
            <version>2.25</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3 -->
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-s3</artifactId>
            <version>1.11.132</version>
        </dependency>

    </dependencies>
    <build>
        <finalName>AmazonExamples</finalName>
    </build>
</project>

Create AmazonS3Bucket Rest Bean

When our java code has successfully created a new Amazon S3 Bucket, we would like to return a confirmation back to a calling client that the bucket has been created. We will do this by returning a Plain Old Java Object which has a special annotation @XmlRootElement which will help JAX-RS to convert this object into JSON or JSON format. The application which called our RESTful Web Service will receive back a response containing a JSON or XML document in response body.

The AmazonS3Bucket class which our Web Service will return is just a custom Plain Old Just Object that I have created. It does not come from Amazon AWS package. Here it’s source code:

package com.appsdeveloperblog.ws.aws.rest;

import javax.xml.bind.annotation.XmlRootElement;

/**
 *
 * @author skargopolov
 */
@XmlRootElement
public class AmazonS3Bucket {
    private String bucketName;

    /**
     * @return the bucketName
     */
    public String getBucketName() {
        return bucketName;
    }

    /**
     * @param bucketName the bucketName to set
     */
    public void setBucketName(String bucketName) {
        this.bucketName = bucketName;
    }
}

Create RESTful Web Service Application Root Resource Class

It is time to create our Web Service Root Resource class which will have one end point declared to accept HTTP Post Request. The below example is just to demonstrate how to create functional Web Service Endpoint. I will add business logic that creates Amazon AWS S3 bucket right after that.

package com.appsdeveloperblog.ws.aws.entrypoints;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.CreateBucketRequest;
import com.amazonaws.services.s3.model.GetBucketLocationRequest;
import com.appsdeveloperblog.ws.aws.rest.AmazonS3Bucket;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

/**
 *
 * @author skargopolov
 */
@Path("/bucket")
public class BucketEntryPoint {

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public AmazonS3Bucket createAmazonS3Bucket(AmazonS3Bucket bucketDetails) {
        
        AmazonS3Bucket returnValue = new AmazonS3Bucket();


        return returnValue;
    }
}

Create Amazon AWS S3 Bucket Java Code

Here is a complete Root Resource Class which declares Web Service Endpoint and adds code the create Amazon AWS S3 Bucket.

package com.appsdeveloperblog.ws.aws.entrypoints;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.CreateBucketRequest;
import com.amazonaws.services.s3.model.GetBucketLocationRequest;
import com.appsdeveloperblog.ws.aws.rest.AmazonS3Bucket;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

/**
 *
 * @author skargopolov
 */
@Path("/bucket")
public class BucketEntryPoint {

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public AmazonS3Bucket createAmazonS3Bucket(AmazonS3Bucket bucketDetails) {
        
        AmazonS3Bucket returnValue = new AmazonS3Bucket();

        BasicAWSCredentials creds = new BasicAWSCredentials("<Your Access Key>", "<Your Secret Key>");
        AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withCredentials(
                new AWSStaticCredentialsProvider(creds))
                .withRegion(Regions.DEFAULT_REGION)
                .build();

        String bucketName = bucketDetails.getBucketName();
        Bucket createdBucket = null;
        
        try {
            if(!(s3Client.doesBucketExist(bucketName)))
            {
            	createdBucket = s3Client.createBucket(
                        new CreateBucketRequest(bucketName)
                        .withCannedAcl(CannedAccessControlList.PublicRead)
                ); 
            }
            
            // Get location.
            String bucketLocation = s3Client.getBucketLocation(new GetBucketLocationRequest(bucketName));
            System.out.println("bucket location = " + bucketLocation);

         } catch (AmazonServiceException ase) {
            System.out.println("Error Message:    " + ase.getMessage());
            System.out.println("HTTP Status Code: " + ase.getStatusCode());
            System.out.println("AWS Error Code:   " + ase.getErrorCode());
            System.out.println("Error Type:       " + ase.getErrorType());
            System.out.println("Request ID:       " + ase.getRequestId());
        } catch (AmazonClientException ace) {
            System.out.println("Error Message: " + ace.getMessage());
        }
        
        if( createdBucket == null ) return returnValue;

        returnValue.setBucketName( createdBucket.getName() );

        return returnValue;
    }
}

Please not that you will need to replace values of <Your access Key> and <Your Secret Key> with your actual values of access key and secret key which you should be able to copy from your AWS Account under “My Security Credentials” section once you sign into AWS Console.

Also, please note how I have set the public read only permissions on the bucket with the CannedAccessControlList.PublicRead:

s3Client.createBucket(
                        new CreateBucketRequest(bucketName)
                        .withCannedAcl(CannedAccessControlList.PublicRead)

Other CannedAccessControlList options that can be applied to the Bucket are:

private – Owner gets FULL_CONTROL. No one else has access rights (default).

public-read-write – Owner gets FULL_CONTROL. The AllUsers group gets READ and WRITE access. Granting this on a bucket is generally not recommended.

aws-exec-read – Owner gets FULL_CONTROL. Amazon EC2 gets READ access to GET an Amazon Machine Image (AMI) bundle from Amazon S3.

authenticated-read – Owner gets FULL_CONTROL. The AuthenticatedUsers group gets READ access.

log-delivery-write – The LogDelivery group gets WRITE and READ_ACP permissions on the bucket.

I hope have this short blog post and sample code to create Amazon AWS S3 bucket was of some value to you.

If you are learning how to build RESTful Web Services for your Mobile Application and looking for useful resources for Full Stack Mobile App Developers, check out my Resources page. I am confident it will bring you some value as well.

Happy learning!