El uso básico de HttpClient del cliente de protocolo HTTP

¡Continúe creando, acelere el crecimiento! Este es el tercer día de mi participación en el "Nuggets Daily New Plan · October Update Challenge", haz clic para ver los detalles del evento

Uso básico de HttpClient

Visión general

HttpClient es un subproyecto de Apache Jakarta Common, que se puede usar para proporcionar un conjunto de herramientas de programación de clientes eficaz, actualizado y rico en funciones que admite el protocolo HTTP y admite la última versión y las recomendaciones del protocolo HTTP.

En comparación con URLConnection que viene con JDK, HttpClient aumenta la facilidad de uso y la flexibilidad, lo que facilita que los clientes envíen solicitudes Http y también facilita el desarrollo de interfaces de prueba, lo que mejora en gran medida la eficiencia del desarrollo.

Los clientes de protocolo HTTP comunes incluyen: httpclient, restTemplate, okHttp

Página web oficial:https://hc.apache.org/index.html

inserte la descripción de la imagen aquí

agregar dependencias

 <dependency>
     <groupId>org.apache.httpcomponents</groupId>
     <artifactId>httpclient</artifactId>
     <version>4.5.13</version>
 </dependency>
复制代码

Obtener solicitud

1. Solicitud GET sin parámetros

    @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. Solicitud GET con parámetros

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

Solicitud POST

1. Solicitud POST sin parámetros

    @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. Solicitud POST con parámetros

    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();
        }
    }
复制代码

grupo de conexiones

HttpClient debe crearse para cada solicitud, y habrá un problema de creación y destrucción frecuentes.La agrupación de conexiones se puede utilizar para resolver este problema.

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();
    }
}
复制代码

Solicitud de configuración de parámetros

Configure los parámetros para las solicitudes, como la configuración de cookies, la configuración de proxy y la configuración de tiempo de espera de solicitud común.

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);
    }
}
复制代码

paquete de herramientas

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();
        }
    }

}

复制代码

prueba

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);
    }
}
复制代码

Supongo que te gusta

Origin juejin.im/post/7150185778079858701
Recomendado
Clasificación