Class S3

java.lang.Object
com.codename1.backend.aws.S3

public final class S3 extends Object

Amazon S3, and anything that speaks its API (MinIO, Cloudflare R2, Backblaze B2, Wasabi, Ceph) -- which is why the endpoint is configurable rather than assembled from a region alone.

Two addressing styles exist and the choice is not cosmetic: virtual-hosted (bucket.s3.region.amazonaws.com) is what AWS requires for new buckets, and path-style (endpoint/bucket/key) is what a local MinIO or a bucket whose name is not DNS-safe needs. Both are supported because a backend is usually developed against the second and deployed against the first.

The presigned URL is the method to reach for from a mobile app: it lets the device upload or download directly and keeps the object bytes out of the server, which is most of the reason to use object storage from an app.

  • Method Details

    • forRegion

      public static S3 forRegion(String region) throws IOException

      AWS S3 in one region, with credentials resolved the usual way.

      The region is taken from AWS_REGION when not given, because that is what Lambda and ECS set and hard-coding it is how a service ends up deployable in exactly one place.

      Throws:
      IOException
    • forEndpoint

      public static S3 forEndpoint(Credentials credentials, String region, String endpoint)

      An S3-compatible endpoint -- MinIO, R2, Ceph -- addressed path-style.

      endpoint is a host with an optional port and an optional scheme: "minio.internal", "localhost:9000", "http://localhost:9000". TLS is assumed unless the endpoint says http:// -- a default of "encrypted" is the one that fails safely.

    • createBucket

      public void createBucket(String bucket) throws IOException

      Creates a bucket, and says nothing when it already exists.

      Usually infrastructure's job rather than the application's, but a first run against a fresh MinIO or a test fixture needs it, and the alternative is a shell script that speaks a protocol this class already speaks.

      Throws:
      IOException
    • putObject

      public String putObject(String bucket, String key, byte[] content, String contentType) throws IOException
      Uploads an object. Returns its ETag, which is the server's receipt.
      Throws:
      IOException
    • getObject

      public byte[] getObject(String bucket, String key) throws IOException
      Downloads an object. Throws when it is missing, rather than returning null.
      Throws:
      IOException
    • headObject

      public S3.ObjectInfo headObject(String bucket, String key) throws IOException
      The object's metadata, or null when it does not exist.
      Throws:
      IOException
    • deleteObject

      public void deleteObject(String bucket, String key) throws IOException
      Throws:
      IOException
    • listObjects

      public List listObjects(String bucket, String prefix, int max) throws IOException

      Lists up to max objects under a prefix.

      ListObjectsV2, and paginated: S3 caps a page at 1000 keys whatever you ask for, and a caller that ignores the continuation token silently sees only the first page. This follows the token until the listing is complete or max is reached.

      Throws:
      IOException
    • presignGet

      public String presignGet(String bucket, String key, int seconds) throws IOException

      A URL that downloads the object without any credentials, for seconds.

      Nothing is sent here: a presigned URL is a computation, so this costs no round trip and can be handed straight to a client.

      Throws:
      IOException
    • presignPut

      public String presignPut(String bucket, String key, int seconds) throws IOException
      The upload counterpart: a URL a client can PUT to, for seconds.
      Throws:
      IOException