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-
|