阅读量:0
HttpClient 5 使用详细教程,代码示例 - 快速上手
依赖
【Maven依赖】
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5 --> <dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5</artifactId> <version>5.1.3</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5-fluent --> <dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5-fluent</artifactId> <version>5.1.3</version> </dependency>
示例
GET请求
【代码】
01
说明
- 类名;
HttpClient5Get.java
02
import java.io.IOException; import org.apache.hc.client5.http.classic.methods.HttpGet; 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.HttpEntity; import org.apache.hc.core5.http.ParseException; import org.apache.hc.core5.http.io.entity.EntityUtils; public class HttpClient5Get { public static void main(String[] args) { String result = get("http://httpbin.org/get"); System.out.println(result); } public static String get(String url) { String resultContent = null; HttpGet httpGet = new HttpGet(url); try (CloseableHttpClient httpclient = HttpClients.createDefault()) { try (CloseableHttpResponse response = httpclient.execute(httpGet)) { // 获取状态码 System.out.println(response.getVersion()); // HTTP/1.1 System.out.println(response.getCode()); // 200 System.out.println(response.getReasonPhrase()); // OK HttpEntity entity = response.getEntity(); // 获取响应信息 resultContent = EntityUtils.toString(entity); } } catch (IOException | ParseException e) { e.printStackTrace(); } return resultContent; } }
【结果】
01
Fluent GET
【说明】
- 使用"Apache HttpClient 5"提供的"Fluent API"可以更便捷的发起"GET"请求,但是可操作的地方较少;
- 只需要"
<artifactId>httpclient5-fluent</artifactId>
"依赖即可运行;
【代码】
01
说明
- 类名;
HttpClient5GetFluent.java
02
import java.io.IOException; import org.apache.hc.client5.http.fluent.Request; import org.apache.hc.client5.http.fluent.Response; public class HttpClient5GetFluent { public static void main(String[] args) { System.out.println(get("http://httpbin.org/get")); } public static String get(String url) { String result = null; try { Response response = Request.get(url).execute(); result = response.returnContent().asString(); } catch (IOException e) { e.printStackTrace(); } return result; } }
【结果】
GET 请求参数
【说明】
- 使用
URIBuilder
的addParameters()
方法来构建"GET"请求的参数;
【代码】
01
说明
- 类名;
HttpClient5GetParams.java
02
import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import org.apache.hc.client5.http.classic.methods.HttpGet; 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.HttpEntity; import org.apache.hc.core5.http.NameValuePair; import org.apache.hc.core5.http.ParseException; import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.http.message.BasicNameValuePair; import org.apache.hc.core5.net.URIBuilder; public class HttpClient5GetParams { public static void main(String[] args) { String result = get("http://httpbin.org/get"); System.out.println(result); } public static String get(String url) { String resultContent = null; HttpGet httpGet = new HttpGet(url); // 表单参数 List<NameValuePair> nvps = new ArrayList<>(); // GET 请求参数 nvps.add(new BasicNameValuePair("username", "SUNxRUN")); nvps.add(new BasicNameValuePair("password", "12345678")); // 增加到请求 URL 中 try { URI uri = new URIBuilder(new URI(url)) .addParameters(nvps) .build(); httpGet.setUri(uri); } catch (URISyntaxException e) { throw new RuntimeException(e); } try (CloseableHttpClient httpclient = HttpClients.createDefault()) { try (CloseableHttpResponse response = httpclient.execute(httpGet)) { // 获取状态码 System.out.println(response.getVersion()); // HTTP/1.1 System.out.println(response.getCode()); // 200 System.out.println(response.getReasonPhrase()); // OK HttpEntity entity = response.getEntity(); // 获取响应信息 resultContent = EntityUtils.toString(entity); } } catch (IOException | ParseException e) { e.printStackTrace(); } return resultContent; } }
【结果】
POST 请求
【说明】
- 参数:“
username=SUNxRUN&password=12345678
”;
【代码】
01
说明
- 类名;
HttpClient5Post.java
02
import java.io.IOException; import java.util.ArrayList; import java.util.List; 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.HttpEntity; import org.apache.hc.core5.http.NameValuePair; import org.apache.hc.core5.http.ParseException; import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.http.message.BasicNameValuePair; public class HttpClient5Post { public static void main(String[] args) { String result = post("http://httpbin.org/post"); System.out.println(result); } public static String post(String url) { String result = null; HttpPost httpPost = new HttpPost(url); // 表单参数 List<NameValuePair> nvps = new ArrayList<>(); // POST 请求参数 nvps.add(new BasicNameValuePair("username", "SUNxRUN")); nvps.add(new BasicNameValuePair("password", "12345678")); httpPost.setEntity(new UrlEncodedFormEntity(nvps)); try (CloseableHttpClient httpclient = HttpClients.createDefault()) { try (CloseableHttpResponse response = httpclient.execute(httpPost)) { System.out.println(response.getVersion()); // HTTP/1.1 System.out.println(response.getCode()); // 200 System.out.println(response.getReasonPhrase()); // OK HttpEntity entity = response.getEntity(); // 获取响应信息 result = EntityUtils.toString(entity); // 确保流被完全消费 EntityUtils.consume(entity); } } catch (IOException | ParseException e) { e.printStackTrace(); } return result; } }
【结果】
Fluent POST
【说明】
- 使用"Apache HttpClient 5"提供的"Fluent API"可以更便捷的发起"POST"请求,但是可操作的地方较少;
- 参数:“
username=SUNxRUN&password=12345678
”;
【代码】
01
说明
- 类名;
HttpClient5PostFluent.java
02
import java.io.IOException; import org.apache.hc.client5.http.fluent.Request; import org.apache.hc.core5.http.message.BasicNameValuePair; public class HttpClient5PostFluent { public static void main(String[] args) { String result = post("http://httpbin.org/post"); System.out.println(result); } public static String post(String url) { String result = null; Request request = Request.post(url); // POST 请求参数 request.bodyForm( new BasicNameValuePair("username", "SUNxRun"), new BasicNameValuePair("password", "12345678")); try { result = request.execute().returnContent().asString(); } catch (IOException e) { e.printStackTrace(); } return result; } }
【结果】
POST JSON 参数
【说明】
- 使用
StringEntity
类存入 JSON 参数;
【代码】
01
说明
- 类名;
HttpClient5PostWithJson.java
02
import java.io.IOException; import org.apache.hc.client5.http.classic.methods.HttpPost; 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.ContentType; import org.apache.hc.core5.http.ParseException; import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.http.io.entity.StringEntity; public class HttpClient5PostWithJson { public static void main(String[] args) { String json = "{" + " \"password\": \"121345678\"," + " \"username\": \"SUNxRUN\"" + "}"; String result = post("http://httpbin.org/post", json); System.out.println(result); } public static String post(String url, String jsonBody) { String result = null; HttpPost httpPost = new HttpPost(url); httpPost.setEntity(new StringEntity(jsonBody, ContentType.APPLICATION_JSON)); try (CloseableHttpClient httpclient = HttpClients.createDefault()) { try (CloseableHttpResponse response = httpclient.execute(httpPost)) { // 获取响应信息 result = EntityUtils.toString(response.getEntity()); } } catch (IOException | ParseException e) { e.printStackTrace(); } return result; } }
【结果】
设置超时
【说明】
- 使用
RequestConfig
对象来配置超时时间;
【代码】
01
说明
- 类名;
HttpClient5GetWithTimeout.java
02
import java.io.IOException; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.config.RequestConfig; 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.HttpEntity; import org.apache.hc.core5.http.ParseException; import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.util.Timeout; public class HttpClient5GetWithTimeout { public static void main(String[] args) { String result = get("http://httpbin.org/get"); System.out.println(result); } public static String get(String url) { String resultContent = null; // 设置超时时间 RequestConfig config = RequestConfig.custom() .setConnectTimeout(Timeout.ofMilliseconds(5000L)) .setConnectionRequestTimeout(Timeout.ofMilliseconds(5000L)) .setResponseTimeout(Timeout.ofMilliseconds(5000L)) .build(); // 请求级别的超时 HttpGet httpGet = new HttpGet(url); //httpGet.setConfig(config); //try (CloseableHttpClient httpclient = HttpClients.createDefault()) { // 客户端级别的超时 try (CloseableHttpClient httpclient = HttpClients.custom().setDefaultRequestConfig(config).build()) { try (CloseableHttpResponse response = httpclient.execute(httpGet)) { // 获取状态码 System.out.println(response.getVersion()); // HTTP/1.1 System.out.println(response.getCode()); // 200 System.out.println(response.getReasonPhrase()); // OK HttpEntity entity = response.getEntity(); // 获取响应信息 resultContent = EntityUtils.toString(entity); } } catch (IOException | ParseException e) { e.printStackTrace(); } return resultContent; } }
异步请求
【代码】
01
说明
- 类名;
HttpClient5Async.java
02
【说明】
- 下面演示三种"HttpClient 5"异步请求方式;
import java.io.IOException; import java.nio.CharBuffer; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; 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.impl.async.CloseableHttpAsyncClient; import org.apache.hc.client5.http.impl.async.HttpAsyncClients; import org.apache.hc.core5.concurrent.FutureCallback; import org.apache.hc.core5.http.ContentType; import org.apache.hc.core5.http.HttpException; import org.apache.hc.core5.http.HttpResponse; import org.apache.hc.core5.http.nio.AsyncRequestProducer; import org.apache.hc.core5.http.nio.support.AsyncRequestBuilder; public class HttpClient5Async { public static void main(String[] args) { getAsync1("http://httpbin.org/get"); getAsync2("http://httpbin.org/get"); getAsync3("http://httpbin.org/get"); } /** * 异步请求 * * @param url * @return */ public static String getAsync1(String url) { try (CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault()) { // 开始 http client httpclient.start(); // 执行请求 SimpleHttpRequest request1 = SimpleHttpRequests.get(url); Future<SimpleHttpResponse> future = httpclient.execute(request1, null); // 等待直到返回完毕 SimpleHttpResponse response1 = future.get(); System.out.println("getAsync1:" + request1.getRequestUri() + "->" + response1.getCode()); } catch (IOException | ExecutionException | InterruptedException e) { throw new RuntimeException(e); } return null; } /** * 异步请求,根据响应情况回调 * * @param url * @return */ public static String getAsync2(String url) { try (CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault()) { // 开始 http client httpclient.start(); // 根据请求响应情况进行回调操作 CountDownLatch latch = new CountDownLatch(1); SimpleHttpRequest request = SimpleHttpRequests.get(url); httpclient.execute(request, new FutureCallback<SimpleHttpResponse>() { @Override public void completed(SimpleHttpResponse response2) { latch.countDown(); System.out.println("getAsync2:" + request.getRequestUri() + "->" + response2.getCode()); } @Override public void failed(Exception ex) { latch.countDown(); System.out.println("getAsync2:" + request.getRequestUri() + "->" + ex); } @Override public void cancelled() { latch.countDown(); System.out.println("getAsync2:" + request.getRequestUri() + " cancelled"); } }); latch.await(); } catch (IOException | InterruptedException e) { throw new RuntimeException(e); } return null; } /** * 异步请求,对响应流做点什么 * * @param url * @return */ public static String getAsync3(String url) { try (CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault()) { // 开始 http client httpclient.start(); // 根据请求响应情况进行回调操作 SimpleHttpRequest request = SimpleHttpRequests.get(url); CountDownLatch latch = new CountDownLatch(1); AsyncRequestProducer producer = AsyncRequestBuilder.get("http://httpbin.org/get").build(); AbstractCharResponseConsumer<HttpResponse> consumer3 = new AbstractCharResponseConsumer<HttpResponse>() { HttpResponse response; @Override protected void start(HttpResponse response, ContentType contentType) throws HttpException, IOException { System.out.println("getAsync3: 开始响应...."); this.response = response; } @Override protected int capacityIncrement() { return Integer.MAX_VALUE; } @Override protected void data(CharBuffer data, boolean endOfStream) throws IOException { System.out.println("getAsync3: 收到数据...."); // Do something useful } @Override protected HttpResponse buildResult() throws IOException { System.out.println("getAsync3: 接收完毕..."); return response; } @Override public void releaseResources() { } }; httpclient.execute(producer, consumer3, new FutureCallback<HttpResponse>() { @Override public void completed(HttpResponse response) { latch.countDown(); System.out.println("getAsync3: " + request.getRequestUri() + "->" + response.getCode()); } @Override public void failed(Exception ex) { latch.countDown(); System.out.println("getAsync3: " + request.getRequestUri() + "->" + ex); } @Override public void cancelled() { latch.countDown(); System.out.println("getAsync3: " + request.getRequestUri() + " cancelled"); } }); latch.await(); } catch (IOException | InterruptedException e) { throw new RuntimeException(e); } return null; } }
【结果】
获取 Cookie
读取文件内容请求
表单登录
Basic Authorization
Digest Authorization
拦截器
【说明】
- "HttpClient 5"中的拦截器可以对请求过程的各个阶段进行拦截处理;
- 通过
HttpClientBuilder
中的关于Interceptor
的方法可以看到可以进行拦截的节点;
【代码】
01
说明
- 类名;
HttpClient5Interceptors.java
02
说明
- 下面编写一个示例,发起三次请求,每次请求都在请求头"herader"中增加一个
request-id
参数,然后对request-id
值为 2 的请求直接响应"404"结束;
import java.io.IOException; import java.util.concurrent.atomic.AtomicLong; import org.apache.hc.client5.http.classic.ExecChain; import org.apache.hc.client5.http.classic.ExecChain.Scope; import org.apache.hc.client5.http.classic.ExecChainHandler; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.impl.ChainElement; 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.ClassicHttpResponse; import org.apache.hc.core5.http.ContentType; import org.apache.hc.core5.http.EntityDetails; import org.apache.hc.core5.http.Header; import org.apache.hc.core5.http.HttpException; import org.apache.hc.core5.http.HttpRequest; import org.apache.hc.core5.http.HttpRequestInterceptor; import org.apache.hc.core5.http.HttpStatus; import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.http.io.entity.StringEntity; import org.apache.hc.core5.http.message.BasicClassicHttpResponse; import org.apache.hc.core5.http.protocol.HttpContext; /** * 展示如何在请求和响应时进行拦截进行自定义处理。 */ public class HttpClient5Interceptors { public static void main(final String[] args) throws Exception { try (final CloseableHttpClient httpclient = HttpClients.custom() // 添加一个请求 id 到请求 header .addRequestInterceptorFirst(new HttpRequestInterceptor() { private final AtomicLong count = new AtomicLong(0); @Override public void process( final HttpRequest request, final EntityDetails entity, final HttpContext context) throws HttpException, IOException { request.setHeader("request-id", Long.toString(count.incrementAndGet())); } }) .addExecInterceptorAfter(ChainElement.PROTOCOL.name(), "custom", new ExecChainHandler() { // 请求 id 为 2 的,模拟 404 响应,并自定义响应的内容。 @Override public ClassicHttpResponse execute( final ClassicHttpRequest request, final Scope scope, final ExecChain chain) throws IOException, HttpException { final Header idHeader = request.getFirstHeader("request-id"); if (idHeader != null && "2".equalsIgnoreCase(idHeader.getValue())) { final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_NOT_FOUND, "Oppsie"); response.setEntity(new StringEntity("bad luck", ContentType.TEXT_PLAIN)); return response; } else { return chain.proceed(request, scope); } } }) .build()) { for (int i = 0; i < 3; i++) { final HttpGet httpget = new HttpGet("http://httpbin.org/get"); try (final CloseableHttpResponse response = httpclient.execute(httpget)) { System.out.println("----------------------------------------"); System.out.println("执行请求 " + httpget.getMethod() + " " + httpget.getUri()); System.out.println(response.getCode() + " " + response.getReasonPhrase()); System.out.println(EntityUtils.toString(response.getEntity())); } } } } }
【结果】
未完待续…