目录
前言
在讲解如何使用HttpClient工具包之前,先简单介绍一下:
HttpClient 是Apache Jakarta Common 下的子项目,是一个支持http协议的客户端编程工具包,使用它可以高效便捷的快速访问不同的网址,发送http请求。
在搭建spring项目时,难免会使用到其他第三方已经实现的API服务,比如搭建微信小程序可能会使用到的微信支付功能,地图的定位功能等。这是我们就需要向其他服务器发送HTTP请求来获取我们需要的数据信息。下面将详细讲述一下如何发送最简单的http请求。
导入依赖
首先创建一个简单的maven工程,然后导入我们需要的依赖:
导入httpclient依赖
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>
后文使用的是junit来测试功能,故需要导入junit依赖:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
编写请求
依赖导入完成就可以正式编码,发送http请求了。发送http请求主要分为三步:
1.创建客户端对象
HttpClient是一个接口,我们可以使用其实现类HttpClients的方法获取一个默认的客户端。这里也可以使用HttpClient的子类CloseableHttpClient来接收客户端对象,他们两个的区别在于,HttpClient是不会关闭连接请求的,而且它是单例模型。而CloseableHttpClient提供了一个close方法来关闭连接请求,它是多例模型,创建时会默认生成一个连接池来方便我们使用。现在一般都是使用CloseableHttpClient。
//创建客户端对象
//CloseableHttpClient httpClient = HttpClients.createDefault();
HttpClient httpClient = HttpClients.createDefault();
2.构建需要发送的请求
这里演示get和post两个请求。get和post请求区别在于我们的请求参数的位置,get请求参数是直接拼接在地址栏里,而post请求参数是由请求主体携带的。
不带参数的get请求:
//构建get请求
HttpGet get = new HttpGet("http://www.baidu.com");
在get请求中,我们可以将请求参数直接拼接在地址后面,如 :
//在地址后面使用?加上key=value的形式拼接,多个参数使用&连接
HttpGet get = new HttpGet("http://localhost:8080/list?id=1&status=1");
在post请求中,我们通过创建HttpEntity实体来构建请求。
HttpEntity是一个接口,需要通过其实现类来创建对象,StringEntity是一个可以创建字符串实体HttpEntity的实现类。
//构建post请求
HttpPost post = new HttpPost("http://localhost:8080/login");
//组装数据
Map<String,Object> map = new HashMap<>();
map.put("username","admin");
map.put("password",123456);
//构建实体
//参数1是请求参数字符串,参数2是请求参数格式
HttpEntity entity = new StringEntity(JSON.toJSONString(map), ContentType.APPLICATION_JSON);
post.setEntity(entity);
因为在设置请求参数格式时,使用到了JSON的一个工具包,需要再导入一个fastjson依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
有时发送请求还需要给请求头附带一些信息,比如在使用jwt令牌校验时,需要使用到token来验证身份,可以使用setHeader方法来给请求头添加信息。
//设置请求头
post.setHeader("token", "eyJhbGciOiJIUzI1NiJ9.eyJlbXBJZCI6MSwiZXhwIjoxNjgzOTkxNTU0fQ.6dBrBB37COSm-K9GHhifqUhXL0UBvK6k0fmy5muRR4w");
3.发送请求获取结果
请求方式构建完成之后就可以直接调用客户端的执行方法来发起请求。返回值需要通过创建一个匿名内部类来重写handleResponse方法来处理,将需要的数据转化为对应的数据类型返回。
//发送请求,获得返回值(有返回值)
String result = httpClient.execute(get, new ResponseHandler<String>() {
//响应处理
public String handleResponse(HttpResponse httpResponse) throws ClientProtocolException, IOException {
//获取响应实体
HttpEntity entity = httpResponse.getEntity();
//将响应实体转换成字符串返回
return EntityUtils.toString(entity);
}
});
System.out.println("result = " + result);
完整测试代码
使用junit单元测试的完整代码:
package com.example.httpClient;
import com.alibaba.fastjson.JSON;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class HttpClientTest {
@Test
public void httpGetTest() throws IOException {
//创建客户端对象
//HttpClient httpClient = HttpClients.createDefault();
CloseableHttpClient httpClient = HttpClients.createDefault();
//构建get请求
HttpGet get = new HttpGet("http://www.baidu.com");
//在地址后面使用?加上key=value的形式拼接,多个参数使用&连接
// HttpGet get = new HttpGet("http://localhost:8080/list?id=1&status=1");
//发送请求,无返回值时
httpClient.execute(get);
//发送请求,获得返回值(有返回值)
String result = httpClient.execute(get, new ResponseHandler<String>() {
//响应处理
public String handleResponse(HttpResponse httpResponse) throws ClientProtocolException, IOException {
//获取响应实体
HttpEntity entity = httpResponse.getEntity();
//将响应实体转换成字符串返回
return EntityUtils.toString(entity);
}
});
System.out.println("result = " + result);
//关闭连接
httpClient.close();
}
@Test
public void httpPostTest() throws IOException {
//创建客户端对象
CloseableHttpClient httpClient = HttpClients.createDefault();
//构建post请求
HttpPost post = new HttpPost("http://localhost:8080/login");
//设置请求头
post.setHeader("token", "eyJhbGciOiJIUzI1NiJ9.eyJlbXBJZCI6MSwiZXhwIjoxNjgzOTkxNTU0fQ.6dBrBB37COSm-K9GHhifqUhXL0UBvK6k0fmy5muRR4w");
//组装数据
Map<String, Object> map = new HashMap<>();
map.put("username", "admin");
map.put("password", 123456);
//构建实体
HttpEntity entity = new StringEntity(JSON.toJSONString(map), ContentType.APPLICATION_JSON);
post.setEntity(entity);
//发送请求,获得返回值(如果有返回)
String result = httpClient.execute(post, httpResponse -> EntityUtils.toString(httpResponse.getEntity()));
System.out.println("result = " + result);
//关闭连接
httpClient.close();
}
}