HTTP协议客户端之HttpClient的基本使用

HttpClient的基本使用

概述

HttpClient 是Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。

HttpClient相比JDK自带的URLConnection,增加了易用性和灵活性,使客户端发送Http请求变得更加容易,而且也方便开发测试接口,大大提高开发的效率。

常用HTTP协议客户端包括有:httpclient、restTemplate、okHttp

官网:https://hc.apache.org/index.html


添加依赖

<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency> 

Get请求

1.无参数的GET请求

@Test public void get() throws IOException { // 创建HttpClient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); // 创建HttpGet请求 HttpGet httpGet = new HttpGet("https://www.baidu.com"); // 响应对象 CloseableHttpResponse response = null; try { // 使用HttpClient发起请求 response = httpClient.execute(httpGet); // 判断响应状态码是否为200 if (response.getStatusLine().getStatusCode() == 200) { // 获取返回数据 HttpEntity httpEntity = response.getEntity();
                String content = EntityUtils.toString(httpEntity, "UTF-8"); // 打印数据长度 log.info("content:{}", content);
            }
        } finally { // 释放连接 if (response != null) {
                response.close();
            }
            httpClient.close();
        }
    }

2.带参数的GET请求

HttpGet httpGet = new HttpGet("https://www.baidu.com/s?wd=java");

POST请求

1.无参数的POST请求

@Test public void post() throws IOException { // 创建HttpClient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); // 创建HttpGet请求 HttpPost httpPost = new HttpPost("http://www.baidu.com"); // 响应对象 CloseableHttpResponse response = null; try { // 使用HttpClient发起请求 response = httpClient.execute(httpPost); // 判断响应状态码是否为200 if (response.getStatusLine().getStatusCode() == 200) { // 获取返回数据 HttpEntity httpEntity = response.getEntity();
                String content = EntityUtils.toString(httpEntity, "UTF-8"); // 打印数据长度 log.info("content:{}", content);
            }
        } finally { // 释放连接 if (response != null) {
                response.close();
            }
            httpClient.close();
        }
    }

2.带参数的POST请求

public static void main(String[] args) throws Exception { // 创建HttpClient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); // 创建HttpPost对象,设置url访问地址 HttpPost httpPost = new HttpPost("https://fanyi.baidu.com/langdetect"); // 声明List集合,封装表单中的参数 List<NameValuePair> params = new ArrayList<NameValuePair>(); // 实际请求地址:https://fanyi.baidu.com/langdetect?query=Java params.add(new BasicNameValuePair("query", "Java")); // 创建表单的Entity对象,第一个参数是封装好的表单数据,第二个参数是编码 UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, "utf8"); //设置表单的Entity对象到Post请求中 httpPost.setEntity(formEntity);

        CloseableHttpResponse response = null; try { // 使用HttpClient发起请求,获取response response = httpClient.execute(httpPost); // 解析响应 if (response.getStatusLine().getStatusCode() == 200) {
                String content = EntityUtils.toString(response.getEntity(), "utf8");
                log.info("content={}", content);
            }
        } finally { // 关闭资源 response.close();
            httpClient.close();
        }
    }

连接池

每次请求都要创建HttpClient,会有频繁创建和销毁的问题,可以使用连接池来解决这个问题。

public class HttpClientPool { public static PoolingHttpClientConnectionManager getHttpClientPool(){ // 创建连接池管理器 PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(); // 设置最大连接数 poolingHttpClientConnectionManager.setMaxTotal(100); // 设置每个主机的最大连接数 poolingHttpClientConnectionManager.setDefaultMaxPerRoute(10); return poolingHttpClientConnectionManager;
    } public static void main(String[] args) { // 使用连接池管理器发起请求 PoolingHttpClientConnectionManager httpClientPool = HttpClientPool.getHttpClientPool(); // 从连接池中获取HttpClient对象 CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(httpClientPool).build();
    }
}

请求参数配置

对请求进行参数配置,如cookie设置,代理设置,以及常用的请求超时时间设置。

public class HttpClientPool { public static PoolingHttpClientConnectionManager getHttpClientPool() { // 创建连接池管理器 PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(); // 设置最大连接数 poolingHttpClientConnectionManager.setMaxTotal(100); // 设置每个主机的最大连接数 poolingHttpClientConnectionManager.setDefaultMaxPerRoute(10); return poolingHttpClientConnectionManager;
    } public static void main(String[] args) throws IOException { // 使用连接池管理器发起请求 PoolingHttpClientConnectionManager httpClientPool = HttpClientPool.getHttpClientPool(); // 从连接池中获取HttpClient对象 CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(httpClientPool).build();

        HttpGet httpGet = new HttpGet("http://www.baidu.com"); // 配置请求信息 RequestConfig config = RequestConfig.custom() // 创建连接的最长时间,单位是毫秒 .setConnectTimeout(1000) // 设置获取连接的最长时间,单位是毫秒 .setConnectionRequestTimeout(500) // 设置数据传输的最长时间,单位是毫秒 .setSocketTimeout(10 * 1000)
                .build(); // 给请求设置请求信息 httpGet.setConfig(config); // 使用HttpClient发起请求,获取response CloseableHttpResponse execute = httpClient.execute(httpGet);
    }
}

工具类封装

HttpClientResult

/**
 * Description: 封装httpClient响应结果
 */ @Data @AllArgsConstructor @NoArgsConstructor public class HttpClientResult implements Serializable { /**
     * 响应状态码
     */ private int code; /**
     * 响应数据
     */ private String content;
}

HttpClientUtils

import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.*; import org.apache.http.client.utils.URIBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.*; /**
 * Description: httpClient工具类
 */ public class HttpClientUtils { // 编码格式。发送编码格式统一用UTF-8 private static final String ENCODING = "UTF-8"; // 设置连接超时时间,单位毫秒。 private static final int CONNECT_TIMEOUT = 6000; // 请求获取数据的超时时间(即响应时间),单位毫秒。 private static final int SOCKET_TIMEOUT = 6000; /**
     * 发送get请求;不带请求头和请求参数
     *
     * @param url 请求地址
     */ public static HttpClientResult doGet(String url) throws Exception { return doGet(url, null, null);
    } /**
     * 发送get请求;带请求参数
     *
     * @param url    请求地址
     * @param params 请求参数集合
     */ public static HttpClientResult doGet(String url, Map<String, String> params) throws Exception { return doGet(url, null, params);
    } /**
     * 发送get请求;带请求头和请求参数
     *
     * @param url     请求地址
     * @param headers 请求头集合
     * @param params  请求参数集合
     */ public static HttpClientResult doGet(String url, Map<String, String> headers, Map<String, String> params) throws Exception { // 创建httpClient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); // 创建访问的地址 URIBuilder uriBuilder = new URIBuilder(url); if (params != null) { Set<Map.Entry<String, String>> entrySet = params.entrySet(); for (Map.Entry<String, String> entry : entrySet) {
                uriBuilder.setParameter(entry.getKey(), entry.getValue());
            }
        } // 创建http对象 HttpGet httpGet = new HttpGet(uriBuilder.build()); /**
         * setConnectTimeout:设置连接超时时间,单位毫秒。
         * setConnectionRequestTimeout:设置从connect Manager(连接池)获取Connection
         * 超时时间,单位毫秒。这个属性是新加的属性,因为目前版本是可以共享连接池的。
         * setSocketTimeout:请求获取数据的超时时间(即响应时间),单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用。
         */ RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
        httpGet.setConfig(requestConfig); // 设置请求头 packageHeader(headers, httpGet); try { // 执行请求并获得响应结果 return getHttpClientResult(httpClient, httpGet);
        } finally { // 释放资源 close(httpClient);
        }
    } /**
     * 发送post请求;不带请求头和请求参数
     *
     * @param url 请求地址
     */ public static HttpClientResult doPost(String url) throws Exception { return doPost(url, null, null);
    } /**
     * 发送post请求;带请求参数
     *
     * @param url    请求地址
     * @param params 参数集合
     */ public static HttpClientResult doPost(String url, Map<String, String> params) throws Exception { return doPost(url, null, params);
    } /**
     * 发送post请求;带请求头和请求参数
     *
     * @param url     请求地址
     * @param headers 请求头集合
     * @param params  请求参数集合
     */ public static HttpClientResult doPost(String url, Map<String, String> headers, Map<String, String> params) throws Exception { // 创建httpClient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); // 创建http对象 HttpPost httpPost = new HttpPost(url); /**
         * setConnectTimeout:设置连接超时时间,单位毫秒。
         * setConnectionRequestTimeout:设置从connect Manager(连接池)获取Connection
         * 超时时间,单位毫秒。这个属性是新加的属性,因为目前版本是可以共享连接池的。
         * setSocketTimeout:请求获取数据的超时时间(即响应时间),单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用。
         */ RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
        httpPost.setConfig(requestConfig); // 设置请求头 /*httpPost.setHeader("Cookie", "");
        httpPost.setHeader("Accept", "application/json");
        httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36");*/ packageHeader(headers, httpPost); // 封装请求参数 packageParam(params, httpPost); try { // 执行请求并获得响应结果 return getHttpClientResult(httpClient, httpPost);
        } finally { // 释放资源 close(httpClient);
        }
    } /**
     * 发送put请求;不带请求参数
     *
     * @param url 请求地址
     */ public static HttpClientResult doPut(String url) throws Exception { return doPut(url, null);
    } /**
     * 发送put请求;带请求参数
     *
     * @param url    请求地址
     * @param params 参数集合
     */ public static HttpClientResult doPut(String url, Map<String, String> params) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPut httpPut = new HttpPut(url);
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
        httpPut.setConfig(requestConfig);

        packageParam(params, httpPut); try { return getHttpClientResult(httpClient, httpPut);
        } finally {
            close(httpClient);
        }
    } /**
     * 发送delete请求;不带请求参数
     *
     * @param url 请求地址
     */ public static HttpClientResult doDelete(String url) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpDelete httpDelete = new HttpDelete(url);
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
        httpDelete.setConfig(requestConfig); try { return getHttpClientResult(httpClient, httpDelete);
        } finally {
            close(httpClient);
        }
    } /**
     * 发送delete请求;带请求参数
     *
     * @param url    请求地址
     * @param params 参数集合
     */ public static HttpClientResult doDelete(String url, Map<String, String> params) throws Exception { if (params == null) {
            params = new HashMap<>();
        }

        params.put("_method", "delete"); return doPost(url, params);
    } /**
     * Description: 封装请求头
     */ public static void packageHeader(Map<String, String> params, HttpRequestBase httpMethod) { // 封装请求头 if (params != null) { Set<Map.Entry<String, String>> entrySet = params.entrySet(); for (Map.Entry<String, String> entry : entrySet) { // 设置到请求头到HttpRequestBase对象中 httpMethod.setHeader(entry.getKey(), entry.getValue());
            }
        }
    } /**
     * Description: 封装请求参数
     */ public static void packageParam(Map<String, String> params, HttpEntityEnclosingRequestBase httpMethod)
            throws UnsupportedEncodingException { // 封装请求参数 if (params != null) {
            List<NameValuePair> nvps = new ArrayList<>(); Set<Map.Entry<String, String>> entrySet = params.entrySet(); for (Map.Entry<String, String> entry : entrySet) {
                nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            } // 设置到请求的http对象中 httpMethod.setEntity(new UrlEncodedFormEntity(nvps, ENCODING));
        }
    } /**
     * Description: 获得响应结果
     */ public static HttpClientResult getHttpClientResult(CloseableHttpClient httpClient, HttpRequestBase httpMethod) throws IOException { try (CloseableHttpResponse httpResponse = httpClient.execute(httpMethod)) { // 获取返回结果 if (httpResponse != null && httpResponse.getStatusLine() != null) { String content = ""; if (httpResponse.getEntity() != null) {
                    content = EntityUtils.toString(httpResponse.getEntity(), ENCODING);
                } return new HttpClientResult(httpResponse.getStatusLine().getStatusCode(), content);
            }
        } return new HttpClientResult(HttpStatus.SC_INTERNAL_SERVER_ERROR, null);
    } /**
     * Description: 释放资源
     */ public static void close(CloseableHttpClient httpClient) throws IOException { if (httpClient != null) {
            httpClient.close();
        }
    }

}

测试

public class HttpClientUtilsTest { /**
     * Description: 测试get无参请求
     */ @Test
    public void testGet() throws Exception {
        HttpClientResult result = HttpClientUtils.doGet("https://www.baidu.com");
        System.out.println(result);
    } /**
     * Description: 测试get带参请求
     */ @Test
    public void testGetWithParam() throws Exception { Map<String, String> params = new HashMap<String, String>();
        params.put("word", "java");
        HttpClientResult result = HttpClientUtils.doGet("url", params);
        System.out.println(result);
    } /**
     * Description: 测试post带请求头不带请求参数
     */ @Test
    public void testPost() throws Exception { Map<String, String> headers = new HashMap<String, String>();
        headers.put("Cookie", "cokie");
        headers.put("Accept", "application/json");
        headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36");
        HttpClientResult result = HttpClientUtils.doPost("url", headers, null);
        System.out.println(result);
    } /**
     * Description: 测试post带参请求
     */ @Test
    public void testPostWithParam() throws Exception { Map<String, String> params = new HashMap<String, String>();
        params.put("word", "java");
        HttpClientResult result = HttpClientUtils.doPost("url", params);
        System.out.println(result);
    }
}
#HTTP##Java##程序员#
全部评论
干货啊,厉害
点赞
送花
回复
分享
发布于 2022-10-15 20:03 山西

相关推荐

猿辅导 Java后端日常实习 800一天
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务