You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2023/02/01 17:40:02 UTC
[httpcomponents-website] branch master updated: Updated quick start and migration guides based on HttpClient 5.2 APIs
This is an automated email from the ASF dual-hosted git repository.
olegk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-website.git
The following commit(s) were added to refs/heads/master by this push:
new 8f582f9 Updated quick start and migration guides based on HttpClient 5.2 APIs
8f582f9 is described below
commit 8f582f9ee6519ab489c110fc9985595f7d8329ff
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Wed Feb 1 16:50:08 2023 +0100
Updated quick start and migration guides based on HttpClient 5.2 APIs
---
.../hc/client5/http/examples/AsyncQuickStart.java | 7 ++-
.../hc/client5/http/examples/QuickStart.java | 41 +++++++++--------
.../migration/examples/HttpClient4Example.java | 20 ++++-----
.../examples/HttpClient5AsyncSimpleExample.java | 46 ++++++++++---------
.../examples/HttpClient5AsyncStreamExample.java | 52 +++++++++++-----------
.../HttpClient5AsyncStreamHttp2Example.java | 47 +++++++++----------
.../examples/HttpClient5ClassicExample.java | 46 +++++++++----------
.../migration-guide/index.md | 20 ++++-----
.../migration-guide/migration-to-async-http2.md | 31 ++++++-------
.../migration-guide/migration-to-async-simple.md | 51 ++++++++++-----------
.../migration-to-async-streaming.md | 41 +++++++++--------
.../migration-guide/migration-to-classic.md | 50 +++++++++++----------
.../migration-guide/preparation.md | 12 ++---
.../httpcomponents-client-5.2.x/quickstart.md | 38 ++++++++--------
14 files changed, 257 insertions(+), 245 deletions(-)
diff --git a/samples/src/main/java/org/apache/hc/client5/http/examples/AsyncQuickStart.java b/samples/src/main/java/org/apache/hc/client5/http/examples/AsyncQuickStart.java
index 1d7d4fe..af2ca7a 100644
--- a/samples/src/main/java/org/apache/hc/client5/http/examples/AsyncQuickStart.java
+++ b/samples/src/main/java/org/apache/hc/client5/http/examples/AsyncQuickStart.java
@@ -27,7 +27,6 @@
package org.apache.hc.client5.http.examples;
-
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.concurrent.CountDownLatch;
@@ -35,8 +34,8 @@ import java.util.concurrent.Future;
import org.apache.hc.client5.http.async.methods.AbstractCharResponseConsumer;
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
-import org.apache.hc.client5.http.async.methods.SimpleHttpRequests;
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
+import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
import org.apache.hc.core5.concurrent.FutureCallback;
@@ -54,7 +53,7 @@ public class AsyncQuickStart {
httpclient.start();
// Execute request
- final SimpleHttpRequest request1 = SimpleHttpRequests.get("http://httpbin.org/get");
+ final SimpleHttpRequest request1 = SimpleRequestBuilder.get("http://httpbin.org/get").build();
final Future<SimpleHttpResponse> future = httpclient.execute(request1, null);
// and wait until response is received
final SimpleHttpResponse response1 = future.get();
@@ -62,7 +61,7 @@ public class AsyncQuickStart {
// One most likely would want to use a callback for operation result
final CountDownLatch latch1 = new CountDownLatch(1);
- final SimpleHttpRequest request2 = SimpleHttpRequests.get("http://httpbin.org/get");
+ final SimpleHttpRequest request2 = SimpleRequestBuilder.get("http://httpbin.org/get").build();
httpclient.execute(request2, new FutureCallback<SimpleHttpResponse>() {
@Override
diff --git a/samples/src/main/java/org/apache/hc/client5/http/examples/QuickStart.java b/samples/src/main/java/org/apache/hc/client5/http/examples/QuickStart.java
index e8e2e23..4cdb59c 100644
--- a/samples/src/main/java/org/apache/hc/client5/http/examples/QuickStart.java
+++ b/samples/src/main/java/org/apache/hc/client5/http/examples/QuickStart.java
@@ -26,25 +26,23 @@
*/
package org.apache.hc.client5.http.examples;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
-import org.apache.hc.client5.http.classic.methods.HttpGet;
-import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.entity.UrlEncodedFormEntity;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
-import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
+import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
import org.apache.hc.core5.http.message.BasicNameValuePair;
public class QuickStart {
public static void main(final String[] args) throws Exception {
try (final CloseableHttpClient httpclient = HttpClients.createDefault()) {
- final HttpGet httpGet = new HttpGet("http://httpbin.org/get");
+ final ClassicHttpRequest httpGet = ClassicRequestBuilder.get("http://httpbin.org/get")
+ .build();
// The underlying HTTP connection is still held by the response object
// to allow the response content to be streamed directly from the network socket.
// In order to ensure correct deallocation of system resources
@@ -52,27 +50,28 @@ public class QuickStart {
// Please note that if response content is not fully consumed the underlying
// connection cannot be safely re-used and will be shut down and discarded
// by the connection manager.
- try (final CloseableHttpResponse response1 = httpclient.execute(httpGet)) {
- System.out.println(response1.getCode() + " " + response1.getReasonPhrase());
- final HttpEntity entity1 = response1.getEntity();
+ httpclient.execute(httpGet, response -> {
+ System.out.println(response.getCode() + " " + response.getReasonPhrase());
+ final HttpEntity entity1 = response.getEntity();
// do something useful with the response body
// and ensure it is fully consumed
EntityUtils.consume(entity1);
- }
+ return null;
+ });
- final HttpPost httpPost = new HttpPost("http://httpbin.org/post");
- final List<NameValuePair> nvps = new ArrayList<>();
- nvps.add(new BasicNameValuePair("username", "vip"));
- nvps.add(new BasicNameValuePair("password", "secret"));
- httpPost.setEntity(new UrlEncodedFormEntity(nvps));
-
- try (final CloseableHttpResponse response2 = httpclient.execute(httpPost)) {
- System.out.println(response2.getCode() + " " + response2.getReasonPhrase());
- final HttpEntity entity2 = response2.getEntity();
+ final ClassicHttpRequest httpPost = ClassicRequestBuilder.post("http://httpbin.org/post")
+ .setEntity(new UrlEncodedFormEntity(Arrays.asList(
+ new BasicNameValuePair("username", "vip"),
+ new BasicNameValuePair("password", "secret"))))
+ .build();
+ httpclient.execute(httpPost, response -> {
+ System.out.println(response.getCode() + " " + response.getReasonPhrase());
+ final HttpEntity entity2 = response.getEntity();
// do something useful with the response body
// and ensure it is fully consumed
EntityUtils.consume(entity2);
- }
+ return null;
+ });
}
}
diff --git a/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient4Example.java b/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient4Example.java
index 5d6bc36..21221b6 100644
--- a/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient4Example.java
+++ b/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient4Example.java
@@ -22,6 +22,10 @@ import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
@@ -42,10 +46,6 @@ import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
public class HttpClient4Example {
public static void main(String... args) throws Exception {
@@ -55,13 +55,13 @@ public class HttpClient4Example {
new String[] { "TLSv1.2" },
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier()))
- .setConnectionTimeToLive(1, TimeUnit.MINUTES)
+ .setConnectionTimeToLive(10, TimeUnit.MINUTES)
.setDefaultSocketConfig(SocketConfig.custom()
- .setSoTimeout(5000)
+ .setSoTimeout(60000)
.build())
.setDefaultRequestConfig(RequestConfig.custom()
- .setConnectTimeout(5000)
- .setSocketTimeout(5000)
+ .setConnectTimeout(60000)
+ .setSocketTimeout(60000)
.setCookieSpec(CookieSpecs.STANDARD_STRICT)
.build())
.build();
@@ -73,8 +73,8 @@ public class HttpClient4Example {
clientContext.setCookieStore(cookieStore);
clientContext.setCredentialsProvider(credentialsProvider);
clientContext.setRequestConfig(RequestConfig.custom()
- .setConnectTimeout(10000)
- .setSocketTimeout(10000)
+ .setConnectTimeout(60000)
+ .setSocketTimeout(60000)
.setCookieSpec(CookieSpecs.STANDARD)
.build());
diff --git a/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient5AsyncSimpleExample.java b/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient5AsyncSimpleExample.java
index c94451b..b7f3bce 100644
--- a/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient5AsyncSimpleExample.java
+++ b/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient5AsyncSimpleExample.java
@@ -18,14 +18,19 @@ package org.apache.hc.client5.migration.examples;
import java.io.IOException;
import java.util.Arrays;
-import java.util.List;
import java.util.concurrent.Future;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
-import org.apache.hc.client5.http.async.methods.SimpleHttpRequests;
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
+import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
import org.apache.hc.client5.http.auth.CredentialsProvider;
+import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.config.TlsConfig;
import org.apache.hc.client5.http.cookie.BasicCookieStore;
import org.apache.hc.client5.http.cookie.CookieStore;
import org.apache.hc.client5.http.cookie.StandardCookieSpec;
@@ -47,37 +52,37 @@ import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.ssl.SSLContexts;
import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.Timeout;
-import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
public class HttpClient5AsyncSimpleExample {
public static void main(String... args) throws Exception {
PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create()
.setTlsStrategy(ClientTlsStrategyBuilder.create()
.setSslContext(SSLContexts.createSystemDefault())
- .setTlsVersions(TLS.V_1_3, TLS.V_1_2)
+ .setTlsVersions(TLS.V_1_3)
.build())
.setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT)
.setConnPoolPolicy(PoolReusePolicy.LIFO)
- .setConnectionTimeToLive(TimeValue.ofMinutes(1L))
+ .setDefaultConnectionConfig(ConnectionConfig.custom()
+ .setSocketTimeout(Timeout.ofMinutes(1))
+ .setConnectTimeout(Timeout.ofMinutes(1))
+ .setTimeToLive(TimeValue.ofMinutes(10))
+ .build())
+ .setDefaultTlsConfig(TlsConfig.custom()
+ .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
+ .setHandshakeTimeout(Timeout.ofMinutes(1))
+ .build())
.build();
CloseableHttpAsyncClient client = HttpAsyncClients.custom()
.setConnectionManager(connectionManager)
.setIOReactorConfig(IOReactorConfig.custom()
- .setSoTimeout(Timeout.ofSeconds(5))
+ .setSoTimeout(Timeout.ofMinutes(1))
.build())
.setDefaultRequestConfig(RequestConfig.custom()
- .setConnectTimeout(Timeout.ofSeconds(5))
- .setResponseTimeout(Timeout.ofSeconds(5))
.setCookieSpec(StandardCookieSpec.STRICT)
.build())
- .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
.build();
client.start();
@@ -89,20 +94,17 @@ public class HttpClient5AsyncSimpleExample {
clientContext.setCookieStore(cookieStore);
clientContext.setCredentialsProvider(credentialsProvider);
clientContext.setRequestConfig(RequestConfig.custom()
- .setConnectTimeout(Timeout.ofSeconds(10))
- .setResponseTimeout(Timeout.ofSeconds(10))
+ .setCookieSpec(StandardCookieSpec.STRICT)
.build());
JsonFactory jsonFactory = new JsonFactory();
ObjectMapper objectMapper = new ObjectMapper(jsonFactory);
- SimpleHttpRequest httpPost = SimpleHttpRequests.post("https://httpbin.org/post");
-
- List<NameValuePair> requestData = Arrays.asList(
- new BasicNameValuePair("name1", "value1"),
- new BasicNameValuePair("name2", "value2"));
-
- httpPost.setBody(objectMapper.writeValueAsString(requestData), ContentType.APPLICATION_JSON);
+ SimpleHttpRequest httpPost = SimpleRequestBuilder.post("https://httpbin.org/post")
+ .setBody(objectMapper.writeValueAsString(Arrays.asList(
+ new BasicNameValuePair("name1", "value1"),
+ new BasicNameValuePair("name2", "value2"))), ContentType.APPLICATION_JSON)
+ .build();
Future<?> future = client.execute(httpPost, new FutureCallback<SimpleHttpResponse>() {
diff --git a/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient5AsyncStreamExample.java b/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient5AsyncStreamExample.java
index 05f22fe..2bf62b5 100644
--- a/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient5AsyncStreamExample.java
+++ b/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient5AsyncStreamExample.java
@@ -17,12 +17,18 @@
package org.apache.hc.client5.migration.examples;
import java.util.Arrays;
-import java.util.List;
import java.util.concurrent.Future;
-import org.apache.hc.client5.http.async.methods.BasicHttpRequests;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.ok2c.hc5.json.http.JsonRequestProducers;
+import com.ok2c.hc5.json.http.JsonResponseConsumers;
+
import org.apache.hc.client5.http.auth.CredentialsProvider;
+import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.config.TlsConfig;
import org.apache.hc.client5.http.cookie.BasicCookieStore;
import org.apache.hc.client5.http.cookie.CookieStore;
import org.apache.hc.client5.http.cookie.StandardCookieSpec;
@@ -34,10 +40,10 @@ import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBu
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.ssl.ClientTlsStrategyBuilder;
import org.apache.hc.core5.concurrent.FutureCallback;
-import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.Message;
import org.apache.hc.core5.http.ssl.TLS;
+import org.apache.hc.core5.http.support.BasicRequestBuilder;
import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.io.CloseMode;
import org.apache.hc.core5.pool.PoolConcurrencyPolicy;
@@ -46,13 +52,6 @@ import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.ssl.SSLContexts;
import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.Timeout;
-import org.apache.http.NameValuePair;
-
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.ok2c.hc5.json.http.JsonRequestProducers;
-import com.ok2c.hc5.json.http.JsonResponseConsumers;
public class HttpClient5AsyncStreamExample {
@@ -60,24 +59,29 @@ public class HttpClient5AsyncStreamExample {
PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create()
.setTlsStrategy(ClientTlsStrategyBuilder.create()
.setSslContext(SSLContexts.createSystemDefault())
- .setTlsVersions(TLS.V_1_3, TLS.V_1_2)
+ .setTlsVersions(TLS.V_1_3)
.build())
.setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT)
.setConnPoolPolicy(PoolReusePolicy.LIFO)
- .setConnectionTimeToLive(TimeValue.ofMinutes(1L))
+ .setDefaultConnectionConfig(ConnectionConfig.custom()
+ .setSocketTimeout(Timeout.ofMinutes(1))
+ .setConnectTimeout(Timeout.ofMinutes(1))
+ .setTimeToLive(TimeValue.ofMinutes(10))
+ .build())
+ .setDefaultTlsConfig(TlsConfig.custom()
+ .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
+ .setHandshakeTimeout(Timeout.ofMinutes(1))
+ .build())
.build();
CloseableHttpAsyncClient client = HttpAsyncClients.custom()
.setConnectionManager(connectionManager)
.setIOReactorConfig(IOReactorConfig.custom()
- .setSoTimeout(Timeout.ofSeconds(5))
+ .setSoTimeout(Timeout.ofMinutes(1))
.build())
.setDefaultRequestConfig(RequestConfig.custom()
- .setConnectTimeout(Timeout.ofSeconds(5))
- .setResponseTimeout(Timeout.ofSeconds(5))
.setCookieSpec(StandardCookieSpec.STRICT)
.build())
- .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
.build();
client.start();
@@ -89,21 +93,19 @@ public class HttpClient5AsyncStreamExample {
clientContext.setCookieStore(cookieStore);
clientContext.setCredentialsProvider(credentialsProvider);
clientContext.setRequestConfig(RequestConfig.custom()
- .setConnectTimeout(Timeout.ofSeconds(10))
- .setResponseTimeout(Timeout.ofSeconds(10))
+ .setCookieSpec(StandardCookieSpec.STRICT)
.build());
JsonFactory jsonFactory = new JsonFactory();
ObjectMapper objectMapper = new ObjectMapper(jsonFactory);
- HttpRequest httpPost = BasicHttpRequests.post("https://httpbin.org/post");
-
- List<NameValuePair> requestData = Arrays.asList(
- new org.apache.http.message.BasicNameValuePair("name1", "value1"),
- new org.apache.http.message.BasicNameValuePair("name2", "value2"));
-
Future<?> future = client.execute(
- JsonRequestProducers.create(httpPost, requestData, objectMapper),
+ JsonRequestProducers.create(
+ BasicRequestBuilder.post("https://httpbin.org/post").build(),
+ Arrays.asList(
+ new org.apache.http.message.BasicNameValuePair("name1", "value1"),
+ new org.apache.http.message.BasicNameValuePair("name2", "value2")),
+ objectMapper),
JsonResponseConsumers.create(jsonFactory),
new FutureCallback<Message<HttpResponse, JsonNode>>() {
diff --git a/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient5AsyncStreamHttp2Example.java b/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient5AsyncStreamHttp2Example.java
index c35e2df..03c3827 100644
--- a/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient5AsyncStreamHttp2Example.java
+++ b/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient5AsyncStreamHttp2Example.java
@@ -17,11 +17,16 @@
package org.apache.hc.client5.migration.examples;
import java.util.Arrays;
-import java.util.List;
import java.util.concurrent.Future;
-import org.apache.hc.client5.http.async.methods.BasicHttpRequests;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.ok2c.hc5.json.http.JsonRequestProducers;
+import com.ok2c.hc5.json.http.JsonResponseConsumers;
+
import org.apache.hc.client5.http.auth.CredentialsProvider;
+import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.cookie.BasicCookieStore;
import org.apache.hc.client5.http.cookie.CookieStore;
@@ -32,21 +37,16 @@ import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.ssl.ClientTlsStrategyBuilder;
import org.apache.hc.core5.concurrent.FutureCallback;
-import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.Message;
+import org.apache.hc.core5.http.message.BasicNameValuePair;
import org.apache.hc.core5.http.ssl.TLS;
+import org.apache.hc.core5.http.support.BasicRequestBuilder;
import org.apache.hc.core5.io.CloseMode;
import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.ssl.SSLContexts;
+import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.Timeout;
-import org.apache.http.NameValuePair;
-
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.ok2c.hc5.json.http.JsonRequestProducers;
-import com.ok2c.hc5.json.http.JsonResponseConsumers;
public class HttpClient5AsyncStreamHttp2Example {
@@ -54,14 +54,17 @@ public class HttpClient5AsyncStreamHttp2Example {
CloseableHttpAsyncClient client = HttpAsyncClients.customHttp2()
.setTlsStrategy(ClientTlsStrategyBuilder.create()
.setSslContext(SSLContexts.createSystemDefault())
- .setTlsVersions(TLS.V_1_3, TLS.V_1_2)
+ .setTlsVersions(TLS.V_1_3)
.build())
.setIOReactorConfig(IOReactorConfig.custom()
- .setSoTimeout(Timeout.ofSeconds(5))
+ .setSoTimeout(Timeout.ofMinutes(1))
+ .build())
+ .setDefaultConnectionConfig(ConnectionConfig.custom()
+ .setSocketTimeout(Timeout.ofMinutes(1))
+ .setConnectTimeout(Timeout.ofMinutes(1))
+ .setTimeToLive(TimeValue.ofMinutes(10))
.build())
.setDefaultRequestConfig(RequestConfig.custom()
- .setConnectTimeout(Timeout.ofSeconds(5))
- .setResponseTimeout(Timeout.ofSeconds(5))
.setCookieSpec(StandardCookieSpec.STRICT)
.build())
.build();
@@ -75,21 +78,19 @@ public class HttpClient5AsyncStreamHttp2Example {
clientContext.setCookieStore(cookieStore);
clientContext.setCredentialsProvider(credentialsProvider);
clientContext.setRequestConfig(RequestConfig.custom()
- .setConnectTimeout(Timeout.ofSeconds(10))
- .setResponseTimeout(Timeout.ofSeconds(10))
+ .setCookieSpec(StandardCookieSpec.STRICT)
.build());
JsonFactory jsonFactory = new JsonFactory();
ObjectMapper objectMapper = new ObjectMapper(jsonFactory);
- HttpRequest httpPost = BasicHttpRequests.post("https://nghttp2.org/httpbin/post");
-
- List<NameValuePair> requestData = Arrays.asList(
- new org.apache.http.message.BasicNameValuePair("name1", "value1"),
- new org.apache.http.message.BasicNameValuePair("name2", "value2"));
-
Future<?> future = client.execute(
- JsonRequestProducers.create(httpPost, requestData, objectMapper),
+ JsonRequestProducers.create(
+ BasicRequestBuilder.post("https://httpbin.org/post").build(),
+ Arrays.asList(
+ new BasicNameValuePair("name1", "value1"),
+ new BasicNameValuePair("name2", "value2")),
+ objectMapper),
JsonResponseConsumers.create(jsonFactory),
new FutureCallback<Message<HttpResponse, JsonNode>>() {
diff --git a/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient5ClassicExample.java b/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient5ClassicExample.java
index 8e19779..c26d2e8 100644
--- a/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient5ClassicExample.java
+++ b/samples/src/main/java/org/apache/hc/client5/migration/examples/HttpClient5ClassicExample.java
@@ -18,11 +18,14 @@ package org.apache.hc.client5.migration.examples;
import java.io.InputStream;
import java.util.Arrays;
-import java.util.List;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.hc.client5.http.ClientProtocolException;
import org.apache.hc.client5.http.auth.CredentialsProvider;
-import org.apache.hc.client5.http.classic.methods.HttpPost;
+import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.cookie.BasicCookieStore;
import org.apache.hc.client5.http.cookie.CookieStore;
@@ -34,11 +37,12 @@ import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder;
+import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.http.io.SocketConfig;
import org.apache.hc.core5.http.io.entity.HttpEntities;
+import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
import org.apache.hc.core5.http.message.BasicNameValuePair;
import org.apache.hc.core5.http.message.StatusLine;
import org.apache.hc.core5.http.ssl.TLS;
@@ -48,31 +52,29 @@ import org.apache.hc.core5.ssl.SSLContexts;
import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.Timeout;
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
public class HttpClient5ClassicExample {
public static void main(String... args) throws Exception {
PoolingHttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
.setSSLSocketFactory(SSLConnectionSocketFactoryBuilder.create()
.setSslContext(SSLContexts.createSystemDefault())
- .setTlsVersions(TLS.V_1_3, TLS.V_1_2)
+ .setTlsVersions(TLS.V_1_3)
.build())
.setDefaultSocketConfig(SocketConfig.custom()
- .setSoTimeout(Timeout.ofSeconds(5))
+ .setSoTimeout(Timeout.ofMinutes(1))
.build())
.setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT)
.setConnPoolPolicy(PoolReusePolicy.LIFO)
- .setConnectionTimeToLive(TimeValue.ofMinutes(1L))
+ .setDefaultConnectionConfig(ConnectionConfig.custom()
+ .setSocketTimeout(Timeout.ofMinutes(1))
+ .setConnectTimeout(Timeout.ofMinutes(1))
+ .setTimeToLive(TimeValue.ofMinutes(10))
+ .build())
.build();
CloseableHttpClient client = HttpClients.custom()
.setConnectionManager(connectionManager)
.setDefaultRequestConfig(RequestConfig.custom()
- .setConnectTimeout(Timeout.ofSeconds(5))
- .setResponseTimeout(Timeout.ofSeconds(5))
.setCookieSpec(StandardCookieSpec.STRICT)
.build())
.build();
@@ -85,22 +87,20 @@ public class HttpClient5ClassicExample {
clientContext.setCookieStore(cookieStore);
clientContext.setCredentialsProvider(credentialsProvider);
clientContext.setRequestConfig(RequestConfig.custom()
- .setConnectTimeout(Timeout.ofSeconds(10))
- .setResponseTimeout(Timeout.ofSeconds(10))
+ .setCookieSpec(StandardCookieSpec.STRICT)
.build());
JsonFactory jsonFactory = new JsonFactory();
ObjectMapper objectMapper = new ObjectMapper(jsonFactory);
- HttpPost httpPost = new HttpPost("https://httpbin.org/post");
-
- List<NameValuePair> requestData = Arrays.asList(
- new BasicNameValuePair("name1", "value1"),
- new BasicNameValuePair("name2", "value2"));
- httpPost.setEntity(HttpEntities.create(outstream -> {
- objectMapper.writeValue(outstream, requestData);
- outstream.flush();
- }, ContentType.APPLICATION_JSON));
+ ClassicHttpRequest httpPost = ClassicRequestBuilder.post("https://httpbin.org/post")
+ .setEntity(HttpEntities.create(outstream -> {
+ objectMapper.writeValue(outstream, Arrays.asList(
+ new BasicNameValuePair("name1", "value1"),
+ new BasicNameValuePair("name2", "value2")));
+ outstream.flush();
+ }, ContentType.APPLICATION_JSON))
+ .build();
JsonNode responseData = client.execute(httpPost, response -> {
if (response.getCode() >= 300) {
diff --git a/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/index.md b/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/index.md
index 447f8e2..ac00d4b 100644
--- a/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/index.md
+++ b/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/index.md
@@ -1,26 +1,26 @@
-# Apache HttpClient 5.0 migration guide
+# Apache HttpClient 5.x migration guide
1. [Migration from HttpClient 4.x](preparation.md)
- Prior to migration from HttpClient 4.x to HttpClient 5.0 it is highly recommended to ensure that HttpClient 4.x is up
+ Prior to migration from HttpClient 4.x to HttpClient 5.x it is highly recommended to ensure that HttpClient 4.x is up
to date and is being used in accordance with the best practices and recommendations.
-1. [Migration to HttpClient 5.0 classic APIs](migration-to-classic.md)
+1. [Migration to HttpClient 5.x classic APIs](migration-to-classic.md)
- When migrating from HttpClient 4.x to HttpClient 5.0 it is generally recommended to migrate to the classic APIs as
+ When migrating from HttpClient 4.x to HttpClient 5.x it is generally recommended to migrate to the classic APIs as
the first step.
-1. [Migration to HttpClient 5.0 async APIs with simple handlers](migration-to-async-simple.md)
+1. [Migration to HttpClient 5.x async APIs with simple handlers](migration-to-async-simple.md)
- When migrating to HttpClient 5.0 async APIs it might be easier to start off by using simple (using in-memory buffers)
+ When migrating to HttpClient 5.x async APIs it might be easier to start off by using simple (using in-memory buffers)
asynchronous handlers.
-1. [Migration to HttpClient 5.0 async APIs](migration-to-async-streaming.md)
+1. [Migration to HttpClient 5.x async APIs](migration-to-async-streaming.md)
- The ultimate goal of the migration process should be to use HttpClient 5.0 async APIs with full content streaming
+ The ultimate goal of the migration process should be to use HttpClient 5.x async APIs with full content streaming
over full-duplex HTTP/1.1 or HTTP/2 connections.
-1. [Migration to HttpClient 5.0 async APIs for HTTP/2 only](migration-to-async-http2.md)
+1. [Migration to HttpClient 5.x async APIs for HTTP/2 only](migration-to-async-http2.md)
- For those scenarios where HTTP/1.1 compatibility is no longer required HttpClient 5.0 provides HTTP/2 optimized
+ For those scenarios where HTTP/1.1 compatibility is no longer required HttpClient 5.x provides HTTP/2 optimized
clients.
diff --git a/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/migration-to-async-http2.md b/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/migration-to-async-http2.md
index 2719383..e9dc287 100644
--- a/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/migration-to-async-http2.md
+++ b/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/migration-to-async-http2.md
@@ -1,4 +1,4 @@
-# Migration to Apache HttpClient 5.0 async APIs for HTTP/2 only
+# Migration to Apache HttpClient 5.x async APIs for HTTP/2 only
For those scenarios where HTTP/1.1 compatibility is no longer required HttpClient 5.0
provides `CloseableHttpAsyncClient` optimized for HTTP/2 protocol with full support for multiplexed request execution
@@ -19,14 +19,17 @@ over a single HTTP/2 connection.
CloseableHttpAsyncClient client = HttpAsyncClients.customHttp2()
.setTlsStrategy(ClientTlsStrategyBuilder.create()
.setSslContext(SSLContexts.createSystemDefault())
- .setTlsVersions(TLS.V_1_3, TLS.V_1_2)
+ .setTlsVersions(TLS.V_1_3)
.build())
.setIOReactorConfig(IOReactorConfig.custom()
- .setSoTimeout(Timeout.ofSeconds(5))
+ .setSoTimeout(Timeout.ofMinutes(1))
+ .build())
+ .setDefaultConnectionConfig(ConnectionConfig.custom()
+ .setSocketTimeout(Timeout.ofMinutes(1))
+ .setConnectTimeout(Timeout.ofMinutes(1))
+ .setTimeToLive(TimeValue.ofMinutes(10))
.build())
.setDefaultRequestConfig(RequestConfig.custom()
- .setConnectTimeout(Timeout.ofSeconds(5))
- .setResponseTimeout(Timeout.ofSeconds(5))
.setCookieSpec(StandardCookieSpec.STRICT)
.build())
.build();
@@ -40,21 +43,19 @@ over a single HTTP/2 connection.
clientContext.setCookieStore(cookieStore);
clientContext.setCredentialsProvider(credentialsProvider);
clientContext.setRequestConfig(RequestConfig.custom()
- .setConnectTimeout(Timeout.ofSeconds(10))
- .setResponseTimeout(Timeout.ofSeconds(10))
+ .setCookieSpec(StandardCookieSpec.STRICT)
.build());
JsonFactory jsonFactory = new JsonFactory();
ObjectMapper objectMapper = new ObjectMapper(jsonFactory);
-
- HttpRequest httpPost = BasicHttpRequests.post("https://nghttp2.org/httpbin/post");
-
- List<NameValuePair> requestData = Arrays.asList(
- new org.apache.http.message.BasicNameValuePair("name1", "value1"),
- new org.apache.http.message.BasicNameValuePair("name2", "value2"));
-
+
Future<?> future = client.execute(
- JsonRequestProducers.create(httpPost, requestData, objectMapper),
+ JsonRequestProducers.create(
+ BasicRequestBuilder.post("https://httpbin.org/post").build(),
+ Arrays.asList(
+ new BasicNameValuePair("name1", "value1"),
+ new BasicNameValuePair("name2", "value2")),
+ objectMapper),
JsonResponseConsumers.create(jsonFactory),
new FutureCallback<Message<HttpResponse, JsonNode>>() {
diff --git a/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/migration-to-async-simple.md b/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/migration-to-async-simple.md
index eb4db96..de567a0 100644
--- a/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/migration-to-async-simple.md
+++ b/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/migration-to-async-simple.md
@@ -1,10 +1,10 @@
-# Migration to Apache HttpClient 5.0 async APIs with simple message handlers
+# Migration to Apache HttpClient 5.x async APIs with simple message handlers
-While HttpClient 5.0 classic APIs are largely compatible with HttpClient 4.0 APIs and can work with
-any `InputStream / OutputStream` based content processing library, the HttpClient 5.0 async APIs are completely
+While HttpClient 5.x classic APIs are largely compatible with HttpClient 4.0 APIs and can work with
+any `InputStream / OutputStream` based content processing library, the HttpClient 5.x async APIs are completely
different.
-HttpClient 5.0 async APIs use an event-driven, reactive programming model based on the concept of channels and event
+HttpClient 5.x async APIs use an event-driven, reactive programming model based on the concept of channels and event
handlers. The channels act as conduits for asynchronous data output. The event handlers react to asynchronous signals or
events and communicate with the opposite endpoint through available channels.
@@ -12,7 +12,7 @@ Both the classic and the async models have their merits. The event-driven, react
convenient for communication protocols with message multiplexing such as HTTP/2. However async APIs generally not
integrate well with `InputStream / OutputStream` based content processing libraries.
-HttpClient 5.0 provides simplified request and response handlers that hide the complexity of the event-driven model by
+HttpClient 5.x provides simplified request and response handlers that hide the complexity of the event-driven model by
buffering message content in memory. Simplified APIs are intended as a temporary, intermediate step in the migration
process or for productive use in scenarios where messages known to be limited in length and the opposite endpoints are
either known to be well-behaved or specifically designed for simple message handlers.
@@ -25,39 +25,43 @@ either known to be well-behaved or specifically designed for simple message hand
PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create()
.setTlsStrategy(ClientTlsStrategyBuilder.create()
.setSslContext(SSLContexts.createSystemDefault())
- .setTlsVersions(TLS.V_1_3, TLS.V_1_2)
+ .setTlsVersions(TLS.V_1_3)
.build())
.setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT)
.setConnPoolPolicy(PoolReusePolicy.LIFO)
- .setConnectionTimeToLive(TimeValue.ofMinutes(1L))
+ .setDefaultConnectionConfig(ConnectionConfig.custom()
+ .setSocketTimeout(Timeout.ofMinutes(1))
+ .setConnectTimeout(Timeout.ofMinutes(1))
+ .setTimeToLive(TimeValue.ofMinutes(10))
+ .build())
+ .setDefaultTlsConfig(TlsConfig.custom()
+ .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
+ .setHandshakeTimeout(Timeout.ofMinutes(1))
+ .build())
.build();
```
Please note that `PoolingAsyncClientConnectionManager` uses different `TLS/SSL` configuration. It also does not
support `SocketConfig` configuration due to differences in the I/O model.
-- Replace `CloseableHttpClient` with `CloseableHttpAsyncClient`.
-
- Select appropriate HTTP version policy. Presently supported policies are: `NEGOTIATE`, `FORCE_HTTP_1`
and `FORCE_HTTP_2`. When the `NEGOTIATE` policy is chosen, HttpClient attempts to negotiate the use of HTTP/2 through
the TLS ALPN (application protocol negotiation) extension as long as it is supported by the default JSSE .
+- Replace `CloseableHttpClient` with `CloseableHttpAsyncClient`.
+
```java
CloseableHttpAsyncClient client = HttpAsyncClients.custom()
.setConnectionManager(connectionManager)
+ .setIOReactorConfig(IOReactorConfig.custom()
+ .setSoTimeout(Timeout.ofMinutes(1))
+ .build())
.setDefaultRequestConfig(RequestConfig.custom()
- .setConnectTimeout(Timeout.ofSeconds(5))
- .setResponseTimeout(Timeout.ofSeconds(5))
.setCookieSpec(StandardCookieSpec.STRICT)
.build())
- .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
.build();
```
- When running on Java 9 or newer HttpClient can use TLS ALPN supported provided by the standard JSSE provider via
- reflection. When running on Java 1.7 or Java 1.8 it can automatically detect Conscrypt TLS library if it is present
- on the classpath and use its JSSE provider instead of the standard one shipped with the platform.
-
- Unlike the classic client the asynchronous one needs to be started in order to be able to execute requests.
```java
@@ -79,20 +83,17 @@ either known to be well-behaved or specifically designed for simple message hand
clientContext.setCookieStore(cookieStore);
clientContext.setCredentialsProvider(credentialsProvider);
clientContext.setRequestConfig(RequestConfig.custom()
- .setConnectTimeout(Timeout.ofSeconds(10))
- .setResponseTimeout(Timeout.ofSeconds(10))
+ .setCookieSpec(StandardCookieSpec.STRICT)
.build());
JsonFactory jsonFactory = new JsonFactory();
ObjectMapper objectMapper = new ObjectMapper(jsonFactory);
- SimpleHttpRequest httpPost = SimpleHttpRequests.post("https://httpbin.org/post");
-
- List<NameValuePair> requestData = Arrays.asList(
- new BasicNameValuePair("name1", "value1"),
- new BasicNameValuePair("name2", "value2"));
-
- httpPost.setBody(objectMapper.writeValueAsString(requestData), ContentType.APPLICATION_JSON);
+ SimpleHttpRequest httpPost = SimpleRequestBuilder.post("https://httpbin.org/post")
+ .setBody(objectMapper.writeValueAsString(Arrays.asList(
+ new BasicNameValuePair("name1", "value1"),
+ new BasicNameValuePair("name2", "value2"))), ContentType.APPLICATION_JSON)
+ .build();
Future<?> future = client.execute(httpPost, new FutureCallback<SimpleHttpResponse>() {
diff --git a/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/migration-to-async-streaming.md b/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/migration-to-async-streaming.md
index bce59d0..2b263e0 100644
--- a/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/migration-to-async-streaming.md
+++ b/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/migration-to-async-streaming.md
@@ -1,4 +1,4 @@
-# Migration to Apache HttpClient 5.0 async APIs
+# Migration to Apache HttpClient 5.x async APIs
HttpClient ships with a number of standard message handlers for the most common scenarios as well as a number of
abstract classes that can be used as a base for custom handlers.
@@ -31,11 +31,11 @@ for [JSON message processing](https://github.com/ok2c/httpcomponents-jackson) us
## Migration steps
-- Depending on the preferred migration path it one might consider migrating to HttpClient 5.0 classic APIs or
- HttpClient 5.0 async APIs with simple message handlers as the first step.
+- Depending on the preferred migration path it one might consider migrating to HttpClient 5.x classic APIs or
+ HttpClient 5.x async APIs with simple message handlers as the first step.
- Replace the existing request generation and response processing code with optimized message handlers shipped with
- HttpClient 5.0 or custom-built handlers.
+ HttpClient 5.x or custom-built handlers.
In this particular instance [JSON message handlers](https://github.com/ok2c/httpcomponents-jackson)
are used to process JSON messages of arbitrary length without intermediate buffering of the entire message.
@@ -46,24 +46,29 @@ for [JSON message processing](https://github.com/ok2c/httpcomponents-jackson) us
PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create()
.setTlsStrategy(ClientTlsStrategyBuilder.create()
.setSslContext(SSLContexts.createSystemDefault())
- .setTlsVersions(TLS.V_1_3, TLS.V_1_2)
+ .setTlsVersions(TLS.V_1_3)
.build())
.setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT)
.setConnPoolPolicy(PoolReusePolicy.LIFO)
- .setConnectionTimeToLive(TimeValue.ofMinutes(1L))
+ .setDefaultConnectionConfig(ConnectionConfig.custom()
+ .setSocketTimeout(Timeout.ofMinutes(1))
+ .setConnectTimeout(Timeout.ofMinutes(1))
+ .setTimeToLive(TimeValue.ofMinutes(10))
+ .build())
+ .setDefaultTlsConfig(TlsConfig.custom()
+ .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
+ .setHandshakeTimeout(Timeout.ofMinutes(1))
+ .build())
.build();
CloseableHttpAsyncClient client = HttpAsyncClients.custom()
.setConnectionManager(connectionManager)
.setIOReactorConfig(IOReactorConfig.custom()
- .setSoTimeout(Timeout.ofSeconds(5))
+ .setSoTimeout(Timeout.ofMinutes(1))
.build())
.setDefaultRequestConfig(RequestConfig.custom()
- .setConnectTimeout(Timeout.ofSeconds(5))
- .setResponseTimeout(Timeout.ofSeconds(5))
.setCookieSpec(StandardCookieSpec.STRICT)
.build())
- .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
.build();
client.start();
@@ -75,21 +80,19 @@ for [JSON message processing](https://github.com/ok2c/httpcomponents-jackson) us
clientContext.setCookieStore(cookieStore);
clientContext.setCredentialsProvider(credentialsProvider);
clientContext.setRequestConfig(RequestConfig.custom()
- .setConnectTimeout(Timeout.ofSeconds(10))
- .setResponseTimeout(Timeout.ofSeconds(10))
+ .setCookieSpec(StandardCookieSpec.STRICT)
.build());
JsonFactory jsonFactory = new JsonFactory();
ObjectMapper objectMapper = new ObjectMapper(jsonFactory);
- HttpRequest httpPost = BasicHttpRequests.post("https://httpbin.org/post");
-
- List<NameValuePair> requestData = Arrays.asList(
- new org.apache.http.message.BasicNameValuePair("name1", "value1"),
- new org.apache.http.message.BasicNameValuePair("name2", "value2"));
-
Future<?> future = client.execute(
- JsonRequestProducers.create(httpPost, requestData, objectMapper),
+ JsonRequestProducers.create(
+ BasicRequestBuilder.post("https://httpbin.org/post").build(),
+ Arrays.asList(
+ new org.apache.http.message.BasicNameValuePair("name1", "value1"),
+ new org.apache.http.message.BasicNameValuePair("name2", "value2")),
+ objectMapper),
JsonResponseConsumers.create(jsonFactory),
new FutureCallback<Message<HttpResponse, JsonNode>>() {
diff --git a/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/migration-to-classic.md b/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/migration-to-classic.md
index ce688ca..222f533 100644
--- a/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/migration-to-classic.md
+++ b/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/migration-to-classic.md
@@ -1,18 +1,18 @@
-# Migration to Apache HttpClient 5.0 classic APIs
+# Migration to Apache HttpClient 5.x classic APIs
-HttpClient 5.0 releases can be co-located with earlier major versions on the same classpath due to versioned package
+HttpClient 5.x releases can be co-located with earlier major versions on the same classpath due to versioned package
namespace and Maven module coordinates.
-HttpClient 5.0 classic APIs are largely compatible with HttpClient 4.0 APIs. Major differences are related to connection
+HttpClient 5.x classic APIs are largely compatible with HttpClient 4.0 APIs. Major differences are related to connection
management configuration, SSL/TLS and timeout settings when building HttpClient instances.
## Migration steps
-- Add HttpClient 5.0 as a new dependency to the project and optionally remove HttpClient 4.x
+- Add HttpClient 5.x as a new dependency to the project and optionally remove HttpClient 4.x
- Remove old `org.apache.http` imports and re-import HttpClient classes from
`org.apache.hc.httpclient5` package namespace. Most old interfaces and classes should resolve automatically. One
- notable exception is `HttpEntityEnclosingRequest` interface In HttpClient 5.0 one can enclose a request entity with
+ notable exception is `HttpEntityEnclosingRequest` interface In HttpClient 5.x one can enclose a request entity with
any HTTP method even if violates semantic of the method.
- There will be compilation errors due to API incompatibilities between version series 4.x and 5.x mostly related to
@@ -23,8 +23,8 @@ management configuration, SSL/TLS and timeout settings when building HttpClient
- Use `SSLConnectionSocketFactoryBuilder` class to create SSL connection socket factories with custom parameters
-- Explicitly specify TLSv1.2 or TLSv1.3 in order to disable older less secure versions of the SSL/TLS protocol. Please note
- all SSL versions are excluded by default.
+- While HttpClient 5 automatically disables all SSL versions and weak TLS versions it may still be advisable to
+ explicitly specify TLSv1.3 as the only enabled version.
- Use `Timeout` class to define timeouts.
@@ -38,18 +38,24 @@ management configuration, SSL/TLS and timeout settings when building HttpClient
for connections to become idle and expire; `LIFO` to re-use all connections equally preventing them from becoming
idle and expiring.
+- Optionally choose a finite total time to live for connections.
+
```java
PoolingHttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
.setSSLSocketFactory(SSLConnectionSocketFactoryBuilder.create()
.setSslContext(SSLContexts.createSystemDefault())
- .setTlsVersions(TLS.V_1_3, TLS.V_1_2)
+ .setTlsVersions(TLS.V_1_3)
.build())
.setDefaultSocketConfig(SocketConfig.custom()
- .setSoTimeout(Timeout.ofSeconds(5))
+ .setSoTimeout(Timeout.ofMinutes(1))
.build())
.setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT)
.setConnPoolPolicy(PoolReusePolicy.LIFO)
- .setConnectionTimeToLive(TimeValue.ofMinutes(1L))
+ .setDefaultConnectionConfig(ConnectionConfig.custom()
+ .setSocketTimeout(Timeout.ofMinutes(1))
+ .setConnectTimeout(Timeout.ofMinutes(1))
+ .setTimeToLive(TimeValue.ofMinutes(10))
+ .build())
.build();
```
@@ -58,14 +64,12 @@ management configuration, SSL/TLS and timeout settings when building HttpClient
- Use response timeout to define the maximum period of inactivity until receipt of response data.
- All base principles and good practices of HttpClient programing still apply. Always re-use client instances. Client
- instances are expensive to create and are thread safe in both HttpClient 4.x and 5.0 series.
+ instances are expensive to create and are thread safe in both HttpClient 4.x and 5.x series.
```java
CloseableHttpClient client = HttpClients.custom()
.setConnectionManager(connectionManager)
.setDefaultRequestConfig(RequestConfig.custom()
- .setConnectTimeout(Timeout.ofSeconds(5))
- .setResponseTimeout(Timeout.ofSeconds(5))
.setCookieSpec(StandardCookieSpec.STRICT)
.build())
.build();
@@ -78,22 +82,20 @@ management configuration, SSL/TLS and timeout settings when building HttpClient
clientContext.setCookieStore(cookieStore);
clientContext.setCredentialsProvider(credentialsProvider);
clientContext.setRequestConfig(RequestConfig.custom()
- .setConnectTimeout(Timeout.ofSeconds(10))
- .setResponseTimeout(Timeout.ofSeconds(10))
+ .setCookieSpec(StandardCookieSpec.STRICT)
.build());
JsonFactory jsonFactory = new JsonFactory();
ObjectMapper objectMapper = new ObjectMapper(jsonFactory);
- HttpPost httpPost = new HttpPost("https://httpbin.org/post");
-
- List<NameValuePair> requestData = Arrays.asList(
- new BasicNameValuePair("name1", "value1"),
- new BasicNameValuePair("name2", "value2"));
- httpPost.setEntity(HttpEntities.create(outstream -> {
- objectMapper.writeValue(outstream, requestData);
- outstream.flush();
- }, ContentType.APPLICATION_JSON));
+ ClassicHttpRequest httpPost = ClassicRequestBuilder.post("https://httpbin.org/post")
+ .setEntity(HttpEntities.create(outstream -> {
+ objectMapper.writeValue(outstream, Arrays.asList(
+ new BasicNameValuePair("name1", "value1"),
+ new BasicNameValuePair("name2", "value2")));
+ outstream.flush();
+ }, ContentType.APPLICATION_JSON))
+ .build();
```
- HTTP response messages in HttpClient 5.x no longer have a status line. Use response code directly.
diff --git a/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/preparation.md b/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/preparation.md
index ed36ccc..42c223e 100644
--- a/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/preparation.md
+++ b/src/site/markdown/httpcomponents-client-5.2.x/migration-guide/preparation.md
@@ -2,7 +2,7 @@
It is strongly encouraged to follow the best practices and common use patterns in programming with Apache HttpClient
4.x. They remain largely unchanged between 4.x and 5.x release series. Correctly written code will be easier to port to
-5.0 APIs and from the classic I/O model to the async I/O model.
+5.x APIs and from the classic I/O model to the async I/O model.
## Preparation steps
@@ -33,11 +33,11 @@ It is strongly encouraged to follow the best practices and common use patterns i
SSLConnectionSocketFactory.getDefaultHostnameVerifier()))
.setConnectionTimeToLive(1, TimeUnit.MINUTES)
.setDefaultSocketConfig(SocketConfig.custom()
- .setSoTimeout(5000)
+ .setSoTimeout(60000)
.build())
.setDefaultRequestConfig(RequestConfig.custom()
- .setConnectTimeout(5000)
- .setSocketTimeout(5000)
+ .setConnectTimeout(60000)
+ .setSocketTimeout(60000)
.setCookieSpec(CookieSpecs.STANDARD_STRICT)
.build())
.build();
@@ -60,8 +60,8 @@ It is strongly encouraged to follow the best practices and common use patterns i
clientContext.setCookieStore(cookieStore);
clientContext.setCredentialsProvider(credentialsProvider);
clientContext.setRequestConfig(RequestConfig.custom()
- .setConnectTimeout(10000)
- .setSocketTimeout(10000)
+ .setConnectTimeout(60000)
+ .setSocketTimeout(60000)
.setCookieSpec(CookieSpecs.STANDARD)
.build());
```
diff --git a/src/site/markdown/httpcomponents-client-5.2.x/quickstart.md b/src/site/markdown/httpcomponents-client-5.2.x/quickstart.md
index 9b3a004..a2ba10c 100644
--- a/src/site/markdown/httpcomponents-client-5.2.x/quickstart.md
+++ b/src/site/markdown/httpcomponents-client-5.2.x/quickstart.md
@@ -29,7 +29,8 @@ HttpClient Quick Start
```
try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
- HttpGet httpGet = new HttpGet("http://httpbin.org/get");
+ ClassicHttpRequest httpGet = ClassicRequestBuilder.get("http://httpbin.org/get")
+ .build();
// The underlying HTTP connection is still held by the response object
// to allow the response content to be streamed directly from the network socket.
// In order to ensure correct deallocation of system resources
@@ -37,27 +38,28 @@ HttpClient Quick Start
// Please note that if response content is not fully consumed the underlying
// connection cannot be safely re-used and will be shut down and discarded
// by the connection manager.
- try (CloseableHttpResponse response1 = httpclient.execute(httpGet)) {
- System.out.println(response1.getCode() + " " + response1.getReasonPhrase());
- HttpEntity entity1 = response1.getEntity();
+ httpclient.execute(httpGet, response -> {
+ System.out.println(response.getCode() + " " + response.getReasonPhrase());
+ final HttpEntity entity1 = response.getEntity();
// do something useful with the response body
// and ensure it is fully consumed
EntityUtils.consume(entity1);
- }
-
- HttpPost httpPost = new HttpPost("http://httpbin.org/post");
- List<NameValuePair> nvps = new ArrayList<>();
- nvps.add(new BasicNameValuePair("username", "vip"));
- nvps.add(new BasicNameValuePair("password", "secret"));
- httpPost.setEntity(new UrlEncodedFormEntity(nvps));
-
- try (CloseableHttpResponse response2 = httpclient.execute(httpPost)) {
- System.out.println(response2.getCode() + " " + response2.getReasonPhrase());
- HttpEntity entity2 = response2.getEntity();
+ return null;
+ });
+
+ ClassicHttpRequest httpPost = ClassicRequestBuilder.post("http://httpbin.org/post")
+ .setEntity(new UrlEncodedFormEntity(Arrays.asList(
+ new BasicNameValuePair("username", "vip"),
+ new BasicNameValuePair("password", "secret"))))
+ .build();
+ httpclient.execute(httpPost, response -> {
+ System.out.println(response.getCode() + " " + response.getReasonPhrase());
+ final HttpEntity entity2 = response.getEntity();
// do something useful with the response body
// and ensure it is fully consumed
EntityUtils.consume(entity2);
- }
+ return null;
+ });
}
```
@@ -88,7 +90,7 @@ HttpClient Quick Start
httpclient.start();
// Execute request
- SimpleHttpRequest request1 = SimpleHttpRequests.get("http://httpbin.org/get");
+ SimpleHttpRequest request1 = SimpleRequestBuilder.get("http://httpbin.org/get").build();
Future<SimpleHttpResponse> future = httpclient.execute(request1, null);
// and wait until response is received
SimpleHttpResponse response1 = future.get();
@@ -96,7 +98,7 @@ HttpClient Quick Start
// One most likely would want to use a callback for operation result
CountDownLatch latch1 = new CountDownLatch(1);
- SimpleHttpRequest request2 = SimpleHttpRequests.get("http://httpbin.org/get");
+ SimpleHttpRequest request2 = SimpleRequestBuilder.get("http://httpbin.org/get").build();
httpclient.execute(request2, new FutureCallback<SimpleHttpResponse>() {
@Override