美文网首页
HTTP协议客户端之HttpClient的基本使用

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

作者: 分布式与微服务 | 来源:发表于2023-03-14 09:15 被阅读0次

    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协议客户端之HttpClient的基本使用

          本文链接:https://www.haomeiwen.com/subject/flffzrtx.html