HttpClient
1.1 简介
HttpClient是一个用于发送HTTP请求的工具,它属于Apache HttpClient组件的一部分,该组件提供了高效的、功能丰富的支持HTTP协议的客户端编程工具包。HttpClient支持HTTP协议的最新版本和建议,实现了所有HTTP方法,包括GET、POST、PUT、HEAD、DELETE、OPTIONS等。
1.2 特性
①基于标准的Java语言;
②支持HTTP 1.0和HTTP 1.1;
③HttpClient支持HTTP的所有方法;
④请求定制化拓展
⑤支持HTTPS/TLS:HttpClient支持HTTPS和TLS加密通信,保证了数据传输的安全性。
1.3基本使用示例
1.3.1 GET请求
public static void testGET() throws IOException, URISyntaxException {
CloseableHttpClient httpClient = HttpClients.createDefault();
URIBuilder builder = new URIBuilder("http://example.com");
// 添加请求参数 -1
builder.setParameter("var1", "param1").setParameter("var2", "param2");
// 添加请求参数 -2
builder.setParameters(new BasicNameValuePair("var1", "param1"), new BasicNameValuePair("var2", "param2"));
// 添加请求参数 -3 addParameter 会保留重名的参数,setParameter会替换
builder.addParameter("var1", "param1").addParameter("var2", "param2");
// 添加路径参数 -1 setPathSegments 会覆盖之前的路径
builder.setPathSegments("pathVar1", "pathVar2");
// 添加路径参数 -2 setPath 会覆盖之前设置的路径
builder.setPath("/pathVar1/pathVar2");
// 添加路径参数 -3 appendPath 路径后面拼接添加
builder.appendPath("pathVar1").appendPath("pathVar2");
builder.appendPathSegments("pathVar1", "pathVar2");
URI url = builder.build();
HttpGet httpget = new HttpGet(url);
CloseableHttpResponse response = httpClient.execute(httpget);
if (response.getCode() == 200) {
System.out.println("调用成功。开始处理响应");
}
response.close();
httpClient.close();
}
1.3.2 POST请求
public static void testPOST() throws IOException {
// 创建httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
// 创建请求对象
HttpPost httpPost = new HttpPost(URL);
// post请求设置请求参数(JSON格式)
StringEntity entity = new StringEntity("123", ContentType.APPLICATION_JSON, "utf-8", false);
// 设置请求参数
httpPost.setEntity(entity);
// 发送请求
CloseableHttpResponse response = httpClient.execute(httpPost);
// 处理响应
if (response.getCode() == 200) {
System.out.println("调用成功。开始处理响应");
}
// 关闭资源
response.close();
httpClient.close();
}
1.3.3 定制化HttpClient
①定制请求参数配置
RequestConfig defaultConfig = RequestConfig.DEFAULT;
// 定制化请求
RequestConfig customConfig = RequestConfig.custom().setAuthenticationEnabled(true) // 允许在请求中使用身份验证信息
.setTargetPreferredAuthSchemes(Arrays.asList("Basic")) // 定义了在请求发送到目标服务器时优先选择的身份验证机制
.setProxyPreferredAuthSchemes(Arrays.asList("Basic", "Digest")) // 定义了在使用代理服务器时优先选择的身份验证机制
.setConnectionRequestTimeout(Timeout.ofMilliseconds(10000)) // 从连接池获取连接的超时时间
.setResponseTimeout(Timeout.ofMilliseconds(10000)) // 等待服务器响应的超时时间。
.setConnectionKeepAlive(Timeout.ofMilliseconds(10000)) // 是否启用长连接策略
.setDefaultKeepAlive(10000L, TimeUnit.MILLISECONDS) // 连接的存活时间
.setContentCompressionEnabled(true) // 是否启用内容压缩
.setHardCancellationEnabled(true) // 是否允许强制取消该请求,即中断正在进行的HTTP操作
.setCookieSpec("") // 设置用于处理Cookie的规范
.setRedirectsEnabled(true) // 是否允许重定向
.setCircularRedirectsAllowed(false) // 是否允许循环重定向
.setMaxRedirects(5) // 最大重定向次数
.setExpectContinueEnabled(true)
// 启用Expect/Continue握手。HTTP/1.1特性,允许客户端在发送实际请求体之前,先发送一个带有Expect: 100-continue的请求头
// 以检查服务器是否愿意接收请求体,有助于避免在服务器拒绝请求时浪费带宽发送大量数据。
.build();
②客户端其他定制选项配置
// 定制化客户端
CloseableHttpClient client = HttpClients.custom().setDefaultRequestConfig(customConfig) // 设置默认的请求配置
.setRequestExecutor() // 设置请求执行器,用于定制请求的执行方式
.setConnectionManager() // 设置一个自定义的连接管理器,管理HTTP连接池和连接的分配
.setConnectionManagerShared() // 指定连接管理器是否为共享的
.setConnectionReuseStrategy() // 设置连接重用策略
.setKeepAliveStrategy() // 设置长连接策略
.setTargetAuthenticationStrategy() // 设置目标主机认证策略
.setProxyAuthenticationStrategy() // 设置代理认证策略
.setUserTokenHandler() // 设置用户令牌处理器
.setSchemePortResolver() // 设置方案端口解析器
.setUserAgent() // 设置用户代理
.setDefaultHeaders() // 设置默认的请求头
.addResponseInterceptorFirst() // 响应拦截器,可以在处理响应前或后,对HTTP响应进行拦截和处理
.addResponseInterceptorLast().addRequestInterceptorFirst() // 添加请求拦截器,对HTTP请求进行拦截和处理
.addRequestInterceptorLast().addExecInterceptorBefore() // 添加执行拦截器,对HTTP请求和响应进行拦截和处理
.addExecInterceptorAfter().replaceExecInterceptor() // 替换已存在的执行拦截器
.addExecInterceptorFirst() // 可以在执行拦截器链的开头或结尾添加新的拦截器
.addExecInterceptorLast().setRetryStrategy() // 设置在遇到特定条件时如何进行HTTP请求的重试
.setProxy() // 设置用于HTTP请求的代理服务器
.setRoutePlanner() // 设置如何计算请求的路由
.setRedirectStrategy() // 设置如何处理HTTP重定向
.setConnectionBackoffStrategy() // 设置在发生连接问题时的退避策略
.setDefaultCookieStore() // 设置用于管理HTTP请求中的Cookie
.setDefaultCredentialsProvider() // 设置用于处理HTTP身份验证的默认凭据提供者
.setDefaultAuthSchemeRegistry() // 设置用于HTTP认证方案的注册表
.setDefaultCookieSpecRegistry() // 设置用于管理Cookie规范的注册表
.setContentDecoderRegistry() // 设置用于管理HTTP内容解码器的注册表
.evictIdleConnections() // 定期清理连接池中的空闲连接
.setProxySelector() // 设置如何选择要使用的代理
.build();
1.3.4 添加报文头
public void addHeader() throws IOException {
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet(URL);
// 添加自定义报文头
httpget.addHeader("custom-head1", "xxxxxxxxx");
httpget.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
httpget.setHeader("Accept-Encoding", "gzip, deflate");
httpget.setHeader("Connection", "keep-alive");
// 添加标准报文头
httpget.addHeader(HttpHeaders.ACCEPT_LANGUAGE, "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3");
httpget.setHeader(HttpHeaders.HOST, URL);
// 使用Header添加报文属性,不常用
Header header = new BasicHeader("Connection", "keep-alive");
httpget.addHeader(header);
CloseableHttpResponse response = httpclient.execute(httpget);
if (response.getCode() == 200) {
System.out.println("调用成功。开始处理响应");
}
response.close();
httpclient.close();
}
1.3.5 添加报文体
①复杂对象
public static void jsonBody() throws IOException, ParseException {
// 创建httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
// 创建请求对象
HttpPost httpPost = new HttpPost(URL);
// post请求设置请求参数(JSON格式)
Map<String, Object> map = new HashMap<>();
map.put("username", "admin");
map.put("password", "123456");
Map<String, Object> extendMap = new HashMap<>();
map.put("exts", extendMap);
extendMap.put("xxx", "111");
JSONObject jsonObject = new JSONObject(map);
StringEntity entity = new StringEntity(jsonObject.toString(), ContentType.APPLICATION_JSON, "utf-8", false);
// 设置请求参数
httpPost.setEntity(entity);
// 发送请求
CloseableHttpResponse response = httpClient.execute(httpPost);
// 处理响应
if (response.getCode() == 200) {
}
// 关闭资源
response.close();
httpClient.close();
}
②表单
public static void formBody() throws Exception {
// 创建默认的httpClient实例.
CloseableHttpClient httpclient = HttpClients.createDefault();
// 创建httppost
HttpPost httppost = new HttpPost(URL);
// 创建参数队列
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("username", "admin"));
formparams.add(new BasicNameValuePair("password", "123456"));
UrlEncodedFormEntity uefEntity;
uefEntity = new UrlEncodedFormEntity(formparams, UTF_8);
httppost.setEntity(uefEntity);
CloseableHttpResponse response = httpclient.execute(httppost);
// 处理响应
if (response.getCode() == 200) {
System.out.println("调用成功。开始处理响应");
}
httpclient.close();
response.close();
}
③文件
public void fileBody() throws IOException {
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httppost = new HttpPost(URL);
FileBody file = new FileBody(new File("C:\\image\\1.jpg"));
StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN);
HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("bin", file).addPart("comment", comment).build();
httppost.setEntity(reqEntity);
CloseableHttpResponse response = httpclient.execute(httppost);
if (response.getCode() == 200) {
System.out.println("调用成功。开始处理响应");
}
HttpEntity rspEntity = response.getEntity();
if (rspEntity != null) {
System.out.println("Response content length: " + rspEntity.getContentLength());
}
EntityUtils.consume(rspEntity);
httpclient.close();
response.close();
}
1.3.6 使用说明
①创建HttpClient
②创建请求方法的实例HttpRequest,并指定请求uri
③构建请求参数HttpEntity及HttpHeader
④发送请求,调用HttpClient对象的execute
⑤获取响应处理HttpResponse
⑥释放资源