Apache HttpClient
简介
HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。
使用HttpClient、可以灵活地发送HTTP请求,并且Apache HttpClient提供了很多自定义的请求内容的API(包括连接超时时间设置等)。方便了开发人员测试接口(基于HTTP协议的),既提高了开发效率,也方便了提高代码的健壮性。(后续的RestTemplate的底层也是HttpClient)因此熟悉掌握HttpClient是很重要的必修内容,掌握了HttpClient后,对于HTTP的协议的了解也会更加深刻。
Apache HttpClient特性
- 基于标准,纯净的Java语言。实现了HTTP1.0和HTTP1.1
- 以可扩展的面向对象的结构实现了 HTTP 全部的方法(
GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE
)。
- 支持 HTTPS 协议。
- 通过 HTTP 代理建立透明的连接。
- 利用 CONNECT 方法通过 HTTP 代理建立隧道的 HTTPS 连接。
Basic,Digest,NTLMv1,NTLMv2,NTLM2Session,SNPNEGO/Kerberos
认证方案。
- 插件式的自定义认证方案。
- 便携可靠的套接字工厂使它更容易的使用第三方解决方案。
- 连接管理器支持多线程应用。支持设置最大连接数,同时支持设置每个主机的最大连接数,发现并关闭过期的连接。
- 自动处理 Set-Cookie 中的 Cookie。
- 插件式的自定义 Cookie 策略。
- Request 的输出流可以避免流中内容直接缓冲到 Socket 服务器。
- Response 的输入流可以有效的从 Socket 服务器直接读取相应内容。
- 在 HTTP 1.0 和 HTTP 1.1 中利用 KeepAlive 保持持久连接。
- 直接获取服务器发送的 response code 和 headers。
- 设置连接超时的能力。
- 实验性的支持 HTTP 1.1 response caching。
使用流程
导入依赖
<dependencies> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.5.13</version> </dependency> </dependencies>
|
创建HttpClient
对象(http客户端对象)
CloseableHttpClient client = HttpClientBuilder.create().build(); CloseableHttpClient client = HttpClients.createDefault();
|
两种方式相同,因为方式二的底层就是方式一。
创建请求方法的实例,并指定URL
。因为HttpClient
是实现了所有Http
请求方法,我们只需要创建请求方法实例(Httpxxx),在方法实例中指定URL即可,例如我们要发送Get请求,就创建HttpGet
对象。
如果需要发送带有参数的请求,可调用HttpGet、HttpPost
共同的setParam(HttpParams params)
来添加参数(该方法已经过时/弃用了);HttpGet
推荐使用单独创建uri,构建自己的带参数的get请求的uri。HttpPost
请求则是调用setEntity(HttpEntity entity)
方法来设置请求参数(可以设置对象)。
发送请求则是HttpClient
的工作,调用HttpClient
的execute(HttpUriRequeset request)
发送请求,该方法会返回一个HttpResponse
(响应模板)
调用HttpResponse
的getAllHeader()
、getHeaders(Sring name)
等方法可以获取服务器的响应头,除此之外还可以获取状态码等。通过HttpResponse
的getEntity()
方法可以获取响应的响应实体,该对象包装了服务器的响应内容,程序可以通过该对象获取服务器的响应内容。
最后需要释放资源,关闭HttpClient
和reseponse
的资源连接
使用实例
GET请求
public class GetClient {
public void doGetTestOne(){ CloseableHttpClient client = HttpClientBuilder.create().build(); HttpGet httpGet = new HttpGet("https://www.cuit.edu.cn/"); CloseableHttpResponse response = null; try{ response = client.execute(httpGet); HttpEntity responseEntity = response.getEntity(); System.out.println("响应状态为:"+response.getStatusLine()); if (responseEntity!=null){ System.out.println("响应内容长度为:"+responseEntity.getContentLength()); System.out.println("响应内容为:"+ EntityUtils.toString(responseEntity)); } } catch (IOException e) { e.printStackTrace(); }finally { try{ if(client!=null){ client.close(); } if (response!=null){ response.close(); } } catch (IOException e) { e.printStackTrace(); } } }
public void doGetTestWayOne(){ CloseableHttpClient client = HttpClientBuilder.create().build();
StringBuilder params = new StringBuilder(); try{ params.append("name=").append(URLEncoder.encode("&","utf-8")).append("&").append("age=24"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); }
HttpGet httpGet = new HttpGet("https://www.cuit.edu.cn/?" + params); CloseableHttpResponse response = null; try{ RequestConfig config = RequestConfig.custom() .setConnectTimeout(5000) .setConnectionRequestTimeout(5000) .setSocketTimeout(5000) .setRedirectsEnabled(true) .build(); httpGet.setConfig(config);
response = client.execute(httpGet);
HttpEntity responseEntity = response.getEntity(); System.out.println("响应状态为:"+response.getStatusLine()); if (responseEntity!=null){ System.out.println("响应内容长度为:"+responseEntity.getContentLength()); System.out.println("响应内容为:"+ EntityUtils.toString(responseEntity,"utf-8")); }
} catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { try { if(client!=null){ client.close(); } if (response!=null){ response.close(); } } catch (IOException e) { e.printStackTrace(); } }
}
public void doGetTestWayTwo(){ CloseableHttpClient client = HttpClientBuilder.create().build(); URI uri = null; try{ ArrayList<NameValuePair> params = new ArrayList<>(); params.add(new BasicNameValuePair("name","10")); params.add(new BasicNameValuePair("age","18")); uri = new URIBuilder().setScheme("http").setHost("www.cuit.edu.cn")
.setParameters(params).build(); System.out.println(uri);
} catch (URISyntaxException e) { e.printStackTrace(); } HttpGet httpGet = new HttpGet(uri);
CloseableHttpResponse response = null; try{ RequestConfig config = RequestConfig.custom() .setConnectTimeout(5000) .setConnectionRequestTimeout(5000) .setSocketTimeout(5000) .setRedirectsEnabled(true).build();
httpGet.setConfig(config); response = client.execute(httpGet);
HttpEntity entity = response.getEntity(); System.out.println("响应状态码:"+response.getStatusLine());
System.out.println("响应内容长度:"+entity.getContentLength()); System.out.println("响应内容:"+EntityUtils.toString(entity,"utf-8")); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { new GetClient().doGetTestWayTwo(); } }
|
POST请求
public class PostClient {
public void doPostTestOne(){ CloseableHttpClient client = HttpClientBuilder.create().build(); HttpPost httpPost = new HttpPost("https://www.cuit.edu.cn/index.htm"); CloseableHttpResponse response = null; try{ response = client.execute(httpPost); HttpEntity entity = response.getEntity(); System.out.println("响应状态码:"+response.getStatusLine()); System.out.println("响应内容长度:"+entity.getContentLength()); System.out.println("响应内容:"+ EntityUtils.toString(entity,"utf-8")); } catch (IOException e) { e.printStackTrace(); }finally { try{ if (client!=null){ client.close(); } if (response!=null){ response.close(); } } catch (IOException e) { e.printStackTrace(); } }
}
public void doPostTestFour(){ CloseableHttpClient client = HttpClientBuilder.create().build();
StringBuilder params = new StringBuilder(); try{ params.append("phone=").append(URLEncoder.encode("admin","utf-8")); params.append("&"); params.append("password=admin");
} catch (UnsupportedEncodingException e) { e.printStackTrace(); }
HttpPost httpPost = new HttpPost("https://www.cuit.edu.cn/?" + params);
httpPost.setHeader("Content-Type","application/json;charset=utf-8"); CloseableHttpResponse response = null; try{ response = client.execute(httpPost); HttpEntity entity = response.getEntity(); System.out.println("状态码:"+response.getStatusLine()); System.out.println("响应内容长度: "+entity.getContentLength()); System.out.println("响应内容: "+entity);
} catch (IOException e) { e.printStackTrace(); } }
public void doPostTestTwo(){ CloseableHttpClient client = HttpClientBuilder.create().build();
HttpPost httpPost = new HttpPost("https://www.cuit.edu.cn/index.htm"); String jsonString = ""; StringEntity stringEntity = new StringEntity(jsonString, "utf-8"); httpPost.setEntity(stringEntity); httpPost.setHeader("Content-Type", "application/json;charset=utf8"); CloseableHttpResponse response = null; try{ response = client.execute(httpPost); HttpEntity entity = response.getEntity(); System.out.println("状态码:"+response.getStatusLine()); System.out.println("响应内容长度:"+entity.getContentLength()); System.out.println("响应内容:"+EntityUtils.toString(entity,"utf-8")); } catch (IOException e) { e.printStackTrace(); } finally { try{ if (client!=null){ client.close(); } if (response!=null){ response.close(); } } catch (IOException e) { e.printStackTrace(); } }
} public static void main(String[] args) { new PostClient().doPostTestTwo(); } }
|
上传文件
public class FileClient {
public void test4(){
CloseableHttpClient client = HttpClientBuilder.create().build(); HttpPost httpPost = new HttpPost("https://www.cuit.edu.cn/file");
CloseableHttpResponse response = null; try{ MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create(); String fileKey = "files"; File file1 = new File("D:\\图片\\《Valorant》3440x1440带鱼屏游戏壁纸_彼岸图网.jpg");
multipartEntityBuilder.addBinaryBody(fileKey,file1, ContentType.DEFAULT_BINARY, URLEncoder.encode(file1.getName(),"utf-8"));
ContentType contentType = ContentType.create("text/plain", StandardCharsets.UTF_8); multipartEntityBuilder.addTextBody("name","等沙利文",contentType); multipartEntityBuilder.addTextBody("age","25",contentType);
HttpEntity httpEntity = multipartEntityBuilder.build(); httpPost.setEntity(httpEntity); response = client.execute(httpPost); HttpEntity entity = response.getEntity(); if (entity!=null){ System.out.println("状态码:"+response.getStatusLine()); System.out.println("响应内容长度:"+entity.getContentLength()); System.out.println("响应内容:"+ EntityUtils.toString(entity,"utf-8")); }
} catch (IOException e) { e.printStackTrace(); } finally { try { if (client!=null){ client.close(); } if (response!=null){ response.close(); } } catch (IOException e) { e.printStackTrace(); } } }
public static void main(String[] args) { new FileClient().test4(); } }
|
Stream请求
public class StreamClient {
public void test5(){ CloseableHttpClient client = HttpClientBuilder.create().build(); HttpPost httpPost = new HttpPost("https://www.cuit.edu.cn/index.htm"); CloseableHttpResponse response = null; try { ByteArrayInputStream is = new ByteArrayInputStream("流啊流~".getBytes(StandardCharsets.UTF_8)); InputStreamEntity ise = new InputStreamEntity(is); httpPost.setEntity(ise);
response = client.execute(httpPost); HttpEntity entity = response.getEntity(); System.out.println("响应状态码:"+response.getStatusLine()); if (entity!=null){ System.out.println("响应内容长度:"+entity.getContentLength()); System.out.println("响应内容:"+ EntityUtils.toString(entity,StandardCharsets.UTF_8)); } } catch (IOException e) { e.printStackTrace(); }finally { try { if (client!=null){ client.close(); } if (response!=null){ response.close(); } } catch (IOException e) { e.printStackTrace(); } } }
public static void main(String[] args) { new StreamClient().test5(); } }
|
-END-