1.11.x had an operation for turning a bucket and object name into a URL. Equivalent functionality should be supported in 2.x.
It's probably better to use 1.11.x for this feature, but here's a really gross, fragile way to do it in 2.x.
URI s3Endpoint = URI.create("https://" + S3Client.serviceMetadata().endpointFor(Region.US_WEST_2));
SdkClientConfiguration sdkClientConfiguration = SdkClientConfiguration.builder()
.option(SdkClientOption.ENDPOINT, s3Endpoint)
.build();
AwsS3ProtocolFactory protocolFactory = AwsS3ProtocolFactory.builder()
.clientConfiguration(sdkClientConfiguration)
.build();
GetObjectRequestMarshaller requestMarshaller = new GetObjectRequestMarshaller(protocolFactory);
GetObjectRequest getRequest = GetObjectRequest.builder().bucket("foo").key("bar").build();
SdkHttpFullRequest httpRequest = requestMarshaller.marshall(getRequest);
URI objectUri = httpRequest.getUri();
It uses internal APIs, so it's subject to break in future SDK versions, and it only uses path-style addressing. It might even be easier to just build the URL manually than use this code...
Well, that's a pretty ingenious workaround!
I am new to S3 and not sure if the way I handle this is consistent.
I just added interceptor by overriding modifyHttpResponse() method by adding url header to the response header!
public class AmazonS3AssetUploadUrlInterceptor implements ExecutionInterceptor {
@Override
public SdkHttpResponse modifyHttpResponse(ModifyHttpResponse context, ExecutionAttributes executionAttributes) {
return context.httpResponse().toBuilder().putHeader("url", context.httpRequest().getUri().toString()).build();
}
}
Resolved in https://github.com/aws/aws-sdk-java-v2/pull/1134
The API is exposed through S3Utilities class.
The API can be used in 2 ways:
1) Directly construct a S3Utilities object
S3Utilities utilities = S3Utilities.builder().region(Region.US_WEST_2).build()
GetUrlRequest request = GetUrlRequest.builder().bucket("foo-bucket").key("key-without-spaces").build()
URL url = pathStyleUtilities.getUrl(request);
2) Use the utilities() method in low-level client (S3Client or S3AsyncClient). This is recommended as SDK will use the same configuration from the low-level client to create the S3Utilities object.
S3Client s3client = S3Client.create();
S3Utilities utilities = s3client.utilities();
GetUrlRequest.builder()
.bucket("foo-bucket")
.key("key-without-spaces")
// Use a different region other than configured on the S3Client/S3Utilities
.region(Region.AP_NORTHEAST_1)
.build();
URL url = pathStyleUtilities.getUrl(request);
How to let gradle to use the newest version?
I have implementation "software.amazon.awssdk:s3:2.5.11"
but I cannot find S3Utilities class.
Most helpful comment
It's probably better to use 1.11.x for this feature, but here's a really gross, fragile way to do it in 2.x.
It uses internal APIs, so it's subject to break in future SDK versions, and it only uses path-style addressing. It might even be easier to just build the URL manually than use this code...