Backend API. Server-side code: this runs in a Codename One backend, not in the app on the device.

public final class S3

  1. Object
  2. S3

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.

Nested types

class S3.ObjectInfoWhat headObject reports.

Methods

public static S3 forRegion(String region) throws IOExceptionAWS S3 in one region, with credentials resolved the usual way.
public static S3 forEndpoint(Credentials credentials, String region, String endpoint)An S3-compatible endpoint – MinIO, R2, Ceph – addressed path-style.
public void createBucket(String bucket) throws IOExceptionCreates a bucket, and says nothing when it already exists.
public String putObject(String bucket, String key, byte[] content, String contentType) throws IOExceptionUploads an object.
public byte[] getObject(String bucket, String key) throws IOExceptionDownloads an object.
public S3.ObjectInfo headObject(String bucket, String key) throws IOExceptionThe object’s metadata, or null when it does not exist.
public void deleteObject(String bucket, String key) throws IOException
public List listObjects(String bucket, String prefix, int max) throws IOExceptionLists up to max objects under a prefix.
public String presignGet(String bucket, String key, int seconds) throws IOExceptionA URL that downloads the object without any credentials, for seconds.
public String presignPut(String bucket, String key, int seconds) throws IOExceptionThe upload counterpart: a URL a client can PUT to, for seconds.

Inherited methods

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.

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.

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.

getObject

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

headObject

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

deleteObject

public void deleteObject(String bucket, String key) 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.

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.

presignPut

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