Configure the URLConnection-based HTTP client
The AWS SDK for Java 2.x offers a lighter-weight UrlConnectionHttpClient HTTP client in comparison to the default
Apache5HttpClient. The UrlConnectionHttpClient is based on Java's
URLConnection.
The UrlConnectionHttpClient loads more quickly than the Apache-based HTTP
client, but has fewer features. Because it loads more quickly, it is a good solution for Java AWS Lambda
functions.
The UrlConnectionHttpClient has several configurable options
Note
The UrlConnectionHttpClient does not support the HTTP PATCH method.
A handful of AWS API operations require PATCH requests. Those operation names usually
start with Update*. The following are several examples.
-
Several
Update*operations in the AWS Security Hub CSPM API and also the BatchUpdateFindings operation -
All Amazon API Gateway API
Update*operations
If you might use the UrlConnectionHttpClient, first refer to the API
Reference for the AWS service that you're using. Check to see if the operations you need
use the PATCH operation.
Note
The UrlConnectionHttpClient does not support a configurable idle connection
timeout.
Connection pooling is managed internally by the JVM. To configure the idle timeout, set
the JVM system property http.keepAlive.time.server to the desired value in
seconds:
$ java -Dhttp.keepAlive.time.server=60 -cp ... App
This is a JVM-global setting that affects all HttpURLConnection usage in the
process, not just SDK clients. If you need per-client control over idle connection timeout,
use the Apache5HttpClient with the connectionMaxIdleTime
setting.
Access the UrlConnectionHttpClient
To configure and use the UrlConnectionHttpClient, you declare a
dependency on the url-connection-client Maven artifact in your
pom.xml file.
Unlike the Apache5HttpClient, the UrlConnectionHttpClient is
not automatically added to your project, so declare it explicitly.
The following example of a pom.xml file shows the dependencies required
to use and configure the HTTP client.
<dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>2.57.3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!-- other dependencies such as s3 or dynamodb --> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>url-connection-client</artifactId> </dependency> </dependencies>
Replace 2.57.3 with the version of the Java SDK that you want to
use. For information about the latest version, see the Maven Central
Each service artifact, such as s3, also adds the
apache5-client and netty-nio-client artifacts to your project
by default. If you use only the UrlConnectionHttpClient, you can exclude those artifacts from each service
dependency to reduce the number of jars in your application.
The following Maven and Gradle examples exclude both artifacts from the
s3 dependency and add the url-connection-client
dependency:
Note
Before version 2.46.0, the default synchronous HTTP client artifact was
apache-client. If you use an earlier version, exclude
apache-client instead of apache5-client.
The UrlConnectionHttpClient supports only synchronous service clients. If you exclude
netty-nio-client and also use asynchronous service clients, such as
S3AsyncClient, add another asynchronous HTTP client.
Use and configure the UrlConnectionHttpClient
You can configure an instance of UrlConnectionHttpClient along with building a service client, or you can
configure a single instance to share across multiple service clients.
With either approach, you use the UrlConnectionHttpClient.Builder
Best practice: dedicate an UrlConnectionHttpClient instance to a service client
If you need to configure an instance of the UrlConnectionHttpClient, we recommend that you build the
dedicated UrlConnectionHttpClient instance. You can do so by using the httpClientBuilder
method of the service client's builder. This way, the lifecycle of the HTTP client is
managed by the SDK, which helps avoid potential memory leaks if the UrlConnectionHttpClient instance is not
closed down when it's no longer needed.
The following example creates an S3Client and configures the embedded
instance of UrlConnectionHttpClient with socketTimeout and proxyConfiguration
values. The proxyConfiguration method takes a Java lambda expression of
type Consumer<ProxyConfiguration.Builder.
Imports
import software.amazon.awssdk.http.SdkHttpClient; import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient; import java.net.URI; import java.time.Duration;
Code
// Singleton: Use the s3Client for all requests. S3Client s3Client = S3Client.builder() .httpClientBuilder(UrlConnectionHttpClient.builder() .socketTimeout(Duration.ofMinutes(5)) .proxyConfiguration(proxy -> proxy.endpoint(URI.create("http://proxy.mydomain.net:8888")))) .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) .build(); // Perform work with the s3Client. s3Client.close(); // Requests completed: Close the s3client.
Alternative approach: share an UrlConnectionHttpClient instance
To help keep resource and memory usage lower for your application, you can configure
an UrlConnectionHttpClient and share it across multiple service clients. The HTTP connection pool will be
shared, which lowers resource usage.
Note
When an UrlConnectionHttpClient instance is shared, you must close it when it is ready to be
disposed. The SDK will not close the instance when the service client is
closed.
The following example configures an URLConnection-based HTTP client that is used by two service clients. The
configured UrlConnectionHttpClient instance is passed to the httpClient method of each
builder. When the service clients and the HTTP client are no longer needed, the code
explicitly closes them. The code closes the HTTP client last.
Imports
import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider; import software.amazon.awssdk.awscore.defaultsmode.DefaultsMode; import software.amazon.awssdk.http.SdkHttpClient; import software.amazon.awssdk.http.urlconnection.ProxyConfiguration; import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.s3.S3Client; import java.net.URI; import java.time.Duration;
Code
SdkHttpClient urlHttpClient = UrlConnectionHttpClient.create(); // Singletons: Use the s3Client and dynamoDbClient for all requests. S3Client s3Client = S3Client.builder() .httpClient(urlHttpClient) .defaultsMode(DefaultsMode.IN_REGION) .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) .build(); DynamoDbClient dynamoDbClient = DynamoDbClient.builder() .httpClient(urlHttpClient) .defaultsMode(DefaultsMode.IN_REGION) .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) .build(); // Perform work with the s3Client and dynamoDbClient. // Requests completed: Close all service clients. s3Client.close(); dynamoDbClient.close(); urlHttpClient.close();
If you don't specify an HTTP client for a service client, the SDK chooses one for
you from the HTTP clients on your classpath. When there's more than one, the SDK uses the one
with the highest priority. Apache5HttpClient has the highest priority, so
the SDK uses it for any service client that doesn't specify an HTTP client, even if
another service client uses the UrlConnectionHttpClient.
In the following example, the dynamoDbClient uses the UrlConnectionHttpClient. The
s3Client doesn't specify an HTTP client, so the SDK uses
Apache5HttpClient:
// The dynamoDbClient uses the UrlConnectionHttpClient. DynamoDbClient dynamoDbClient = DynamoDbClient.builder() .httpClientBuilder(UrlConnectionHttpClient.builder()) .build(); // The s3Client doesn't specify an HTTP client, so the SDK uses the Apache5HttpClient. S3Client s3Client = S3Client.create(); // Perform work with the s3Client and dynamoDbClient. dynamoDbClient.close(); s3Client.close();
To choose the HTTP client for a service client, specify it explicitly:
DynamoDbClient dynamoDbClient = DynamoDbClient.builder() .httpClientBuilder(UrlConnectionHttpClient.builder()) .build(); S3Client s3Client = S3Client.builder() .httpClientBuilder(Apache5HttpClient.builder()) // Explicitly use the Apache5HttpClient. .build(); // Perform work with the s3Client and dynamoDbClient. dynamoDbClient.close(); s3Client.close();
Note
To explicitly use the Apache5HttpClient, add a dependency on
the apache5-client artifact. For more information about adding the
dependency, see Configuration needed.
Before version 2.22.0, the SDK threw an SdkClientException
with the message that multiple HTTP implementations were found on the classpath.
To avoid the exception, specify the HTTP client for each service client.
Proxy configuration example
The following code snippet uses the proxy configuration builder for the URL connection HTTP client
SdkHttpClient urlHttpClient = UrlConnectionHttpClient.builder() .proxyConfiguration(ProxyConfiguration.builder() .endpoint(URI.create("http://example.com:1234")) .username("username") .password("password") .addNonProxyHost("localhost") .addNonProxyHost("host.example.com") .build()) .build();
The equivalent Java system properties for the proxy configuration are shown in the following command line snippet.
$ java -Dhttp.proxyHost=example.com -Dhttp.proxyPort=1234 -Dhttp.proxyUser=username \ -Dhttp.proxyPassword=password -Dhttp.nonProxyHosts=localhost|host.example.com -cp ... App
The equivalent setup that uses environment variables is:
// Set the following environment variables. // $ export HTTP_PROXY="http://username:password@example.com:1234" // $ export NO_PROXY="localhost|host.example.com" // Set the 'useSystemPropertyValues' to false on the proxy configuration. SdkHttpClient apacheHttpClient = UrlConnectionHttpClient.builder() .proxyConfiguration(ProxyConfiguration.builder() .useSystemPropertyValues(Boolean.FALSE) .build()) .build(); // Run the application. // $ java -cp ... App
Note
The URLConnection-based HTTP client does not currently support HTTPS proxy system properties or the HTTPS_PROXY environment variable.