1 概述
在实际开发时,常常需要调用远程的web api来处理业务。发送请求并获得相应结果的这个过程可以使用Apache提供的结果方法——HttpClient。HttpClient专为扩展而设计,同时为基本HTTP协议提供强大的支持。尽管 java.net 包提供了通过 HTTP 访问资源的基本功能,但它并没有提供许多应用程序所需的全部灵活性或功能。HttpClient试图通过提供一个高效,最新且功能丰富的包来填补这一空白,该包实现了最新HTTP标准和建议的客户端。
目前已更新到了5.1版本,本篇文章使用的版本为4.5.9。
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.9</version>
</dependency>
2 执行请求的原理
1 Java语言是面向对象的,HttpClient在设计的时候同时遵循了这一原则,方法的调用描述了请求和响应的过程。了解该过程可以参考我的前两篇文章tcp/ip 协议族 、http报文说明。
调用Web API 获得数据的整个流程 其实就是客服端向服务器发送请求报文并接收处理服务器响应的报文
在发送报文与接收报文的过程中,使用了tcp/ip协议族中位于不同层的网络协议。如HTTP,TCP,IP协议等。在看代码样例时,可以参考上述文章,加深对方法调用的理解
3 发送get请求(报文)
get请求报文信息入下:
/**
* @author lyf
* @projectName httpclients-study
* @date 2022/8/22 下午 02:27
* @description get请求
*/
public class GetExecution {
String requestUrl="http://10.132.37.98:8006//Personal/ElistQuery.asmx/ByUserID?EmployeeID=";
/***
* 使用确定url地址来确定请求
* @param param
* @return
* @throws IOException
*/
public String sendGetRequest(String param) throws IOException {
//建立tcp 连接
CloseableHttpClient httpClient = HttpClients.createDefault();
//get 请求,
HttpGet get=new HttpGet(requestUrl+param);
//获得响应报文-response
CloseableHttpResponse httpResponse = httpClient.execute(get);
//获得响应报文的主体部分
HttpEntity entity=httpResponse.getEntity();
//主体部分转为字符串
String responseBodyStr = EntityUtils.toString(entity, "utf-8");
return responseBodyStr;
}
/**
* 使用URI资源定位来发送get请求
* @param param
* @return
* @throws URISyntaxException
* @throws IOException
*/
public String sendGetRequest1(String param) throws URISyntaxException, IOException {
CloseableHttpClient httpClient = HttpClients.createDefault();
//使用URI来定位服务器上的资源,
URI uri= new URIBuilder()
//设置协议方案
.setScheme("http")
//请求主机,可以使用域名或是具体IP地址
.setHost("10.132.37.98")
//请求端口
.setPort(8006)
//请求路径
.setPath("/Personal/ElistQuery.asmx/ByUserID")
//设置参数,多个参数时,可以多次调用setParameter()方法
.setParameter("EmployeeID",param)
.build();
HttpGet get=new HttpGet(uri);
CloseableHttpResponse httpResponse = httpClient.execute(get);
HttpEntity entity=httpResponse.getEntity();
//获得响应报文中的报文主体
String responseBodyStr = EntityUtils.toString(entity, "utf-8");
return responseBodyStr;
}
}
2.在发送请求时,有两种方式定位我们的网络资源。URL和URI,与 URI(统一资源标识符)相比,我们更熟悉 URL(UniformResource Locator,统一资源定位符)。URL正是使用 Web 浏览器等访问 Web 页面时需要输入的网页地址。URI 用字符串标识某一互联网资源,而 URL表示资源的地点(互联
网上所处的位置)。可见 URL是 URI 的子集。URI的结构如下图。sendGetRequest1就是根据该结构设置的请求资源信息。
2 发送Post请求(报文)
/**
* @author lyf
* @projectName httpclients-study
* @date 2022/8/22 下午 03:57
* @description 发送post请求
*/
public class PostExecution {
String requestUrl="http://10.132.37.98:8006//Personal/ElistQuery.asmx/ByUserID";
public String sendPostRequest(String param) throws IOException {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost post=new HttpPost(requestUrl);
//设置请求首部
post.setHeader("Content-Type","application/x-www-form-urlencoded");
//设置请求体
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("EmployeeID", param));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
post.setEntity(entity);
//执行请求并获得响应
CloseableHttpResponse response = httpClient.execute(post);
//获得响应报文中的报文主体
String responseBodyStr = EntityUtils.toString(entity, "utf-8");
return responseBodyStr;
}
}
在 HTTP 首部中以 Content-Type 这个字段来表示报文主体的对象类型。
Content-Type: application/x-www-form-urlencoded,表示请求数据被编码为名称/值对
即EmployeeID=param