httpClient的使用(附代码示例)-程序员宅基地

技术标签: java  青少年编程  Java工具类  开发语言  

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
http之HttpClient工具类


前言

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


一、httpClient是什么?httpClient支持的方法

httpClient:HTTP 协议是 Internet 上使用得最多、最重要的协议之一,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。Commons HttpClient项目现已终止,不再开发。 它已被Apache HttpComponents项目里的HttpClient和HttpCore模块取代,它们提供了更好的性能和更大的灵活性

HTTP :GET、POST、PUT、HEAD、DELETE、HEAD、OPTIONS 等

二、使用步骤

1.引入库

代码如下(示例):

import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.config.SocketConfig;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
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 org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.charset.CodingErrorAction;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


## 2.代码示例

代码如下(示例):

/**
 * @descriptions: HttpClient发送Get请求和Post请求的封装类
 * @author: [email protected]
 * @date: 2024/1/29 19:19
 * @version: 1.0
 */
@Component
public class HttpClientUtil {
    /** 从连接池中获取连接的超时时间(单位:ms) */
    private static final int CONNECTION_REQUEST_TIMEOUT = 20000;

    /** 与服务器连接的超时时间(单位:ms) */
    private static final int CONNECTION_TIMEOUT = 20000;

    /** 从服务器获取响应数据的超时时间(单位:ms) */
    private static final int SOCKET_TIMEOUT = 25000;

    /** 连接池的最大连接数 */
    private static final int MAX_CONN_TOTAL = 100;

    /** 每个路由上的最大连接数 */
    private static final int MAX_CONN_PER_ROUTE = 50;

    /** 用户代理配置 */
    private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36";

    /** HttpClient对象 */
    private static CloseableHttpClient httpClient = null;

    /** Connection配置对象 */
    private static ConnectionConfig connectionConfig = null;

    /** Socket配置对象 */
    private static SocketConfig socketConfig = null;

    /** Request配置对象 */
    private static RequestConfig requestConfig = null;

    /** Cookie存储对象 */
    private static BasicCookieStore cookieStore = null;


    static {
        init();
    }

    /**
     * 全局对象初始化
     */
    private static void init() {
        // 创建Connection配置对象
        connectionConfig = ConnectionConfig.custom()
                .setMalformedInputAction(CodingErrorAction.IGNORE)
                .setUnmappableInputAction(CodingErrorAction.IGNORE)
                .setCharset(Consts.UTF_8).build();

        // 创建Socket配置对象
        socketConfig = SocketConfig.custom().setTcpNoDelay(true).build();

        // 创建Request配置对象
        requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
                .setConnectTimeout(CONNECTION_TIMEOUT)
                .setSocketTimeout(SOCKET_TIMEOUT)
                .build();

        // 创建Cookie存储对象(服务端返回的Cookie保存在CookieStore中,下次再访问时才会将CookieStore中的Cookie发送给服务端)
        cookieStore = new BasicCookieStore();

        // 创建HttpClient对象
        httpClient = HttpClients.custom()
                .setDefaultConnectionConfig(connectionConfig)
                .setDefaultSocketConfig(socketConfig)
                .setDefaultRequestConfig(requestConfig)
                .setDefaultCookieStore(cookieStore)
                .setUserAgent(USER_AGENT)
                .setMaxConnTotal(MAX_CONN_TOTAL)
                .setMaxConnPerRoute(MAX_CONN_PER_ROUTE)
                .build();
    }

    /**
     * 发送Get请求
     * @param url 请求的地址
     * @param parameters 请求的数据
     * @param cookies 请求的Cookie信息
     * @param headers 请求的头部信息
     * @param charset 请求数据的字符编码
     */
    public static HttpResult sendGet(String url, Map<String, String> parameters, Header[] headers, Cookie[] cookies, String charset){
        HttpResult httpResult = null;
        try {
            // 创建URI并设置参数
            URIBuilder builder = new URIBuilder(url);
            if (parameters != null && !parameters.isEmpty()) {
                builder.addParameters(assemblyParameter(parameters));
            }
            if (charset != null) {
                builder.setCharset(Charset.forName(charset));
            }
            URI uri = builder.build();

            // 创建HttpGet
            HttpGet httpGet = new HttpGet(uri);

            // 设置Header
            if (headers != null) {
                /**
                 * httpGet.setHeaders(headers),重新设置Header,前面set或者add的Header都会被去掉
                 * httpGet.setHeader(header):如果已经有了同名的Header,则覆盖同名的Header,如果没有,则添加Header
                 * httpGet.addHeader(header):不管是否已经有了同名的Header,都添加Header,可能会导致存在同名的Header
                 */
                httpGet.setHeaders(headers);
            }

            // 设置Cookie
            if (cookies != null) {
                /**
                 * Cookie必须通过Header来设置
                 */
                httpGet.setHeader("cookie", assemblyCookie(cookies));
            }

            // 发送Post请求并得到响应结果
            httpResult = httpClient.execute(httpGet, getResponseHandler());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return httpResult;
    }

    /**
     * 发送Post请求(Form格式的数据)
     * @param url 请求的地址
     * @param parameters 请求的Form数据
     * @param cookies 请求的Cookie信息
     * @param headers 请求的头部信息
     * @param charset 请求数据的字符编码
     */
    public static HttpResult sendPostForm(String url, Map<String, String> parameters, Header[] headers, Cookie[] cookies, String charset) {
        HttpResult httpResult = null;
        try {
            // 创建HttpPost
            HttpPost httpPost = new HttpPost(url);

            // 设置请求数据
            if (parameters != null && !parameters.isEmpty()) {
                httpPost.setEntity(assemblyFormEntity(parameters, charset));
            }

            // 设置Header
            if (headers != null) {
                /**
                 * httpGet.setHeaders(headers),重新设置Header,前面set或者add的Header都会被去掉
                 * httpGet.setHeader(header):如果已经有了同名的Header,则覆盖同名的Header,如果没有,则添加Header
                 * httpGet.addHeader(header):不管是否已经有了同名的Header,都添加Header,可能会导致存在同名的Header
                 */
                httpPost.setHeaders(headers);
            }

            // 设置Cookie
            if (cookies != null) {
                /**
                 * Cookie必须通过Header来设置
                 */
                httpPost.setHeader("cookie", assemblyCookie(cookies));
            }

            // 发送Post请求并得到响应结果
            httpResult = httpClient.execute(httpPost, getResponseHandler());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return httpResult;
    }

    /**
     * 发送Post请求(Json格式的数据)
     * @param url 请求的地址
     * @param jsonData 请求的Json数据
     * @param headers 请求的头部信息
     * @param charset 请求数据的字符编码
     */
    public static HttpResult sendPostJson(String url, String jsonData, Header[] headers, String charset) {
        HttpResult httpResult = null;

        try {
            // 创建HttpPost
            HttpPost httpPost = new HttpPost(url);

            // 设置请求数据
            httpPost.setEntity(assemblyStringEntity(jsonData, charset));

            // 设置Header
            if (headers != null) {
                /**
                 * httpGet.setHeaders(headers),重新设置Header,前面set或者add的Header都会被去掉
                 * httpGet.setHeader(header):如果已经有了同名的Header,则覆盖同名的Header,如果没有,则添加Header
                 * httpGet.addHeader(header):不管是否已经有了同名的Header,都添加Header,可能会导致存在同名的Header
                 */
                httpPost.setHeaders(headers);
            }
            // 发送Post请求并得到响应结果
            httpResult = httpClient.execute(httpPost, getResponseHandler());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return httpResult;
    }

    /**
     * 获取响应结果处理器(把响应结果封装成HttpResult对象)
     */
    private static ResponseHandler<HttpResult> getResponseHandler() {
        ResponseHandler<HttpResult> responseHandler = new ResponseHandler<HttpResult>() {
            @Override
            public HttpResult handleResponse(HttpResponse httpResponse) throws ClientProtocolException, IOException {
                if (httpResponse == null) {
                    throw new ClientProtocolException("HttpResponse is null");
                }

                StatusLine statusLine = httpResponse.getStatusLine();
                HttpEntity httpEntity = httpResponse.getEntity();
                if (statusLine == null) {
                    throw new ClientProtocolException("HttpResponse contains no StatusLine");
                }
                if (statusLine.getStatusCode() != 200) {
                    throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
                }
                if (httpEntity == null) {
                    throw new ClientProtocolException("HttpResponse contains no HttpEntity");
                }

                HttpResult httpResult = new HttpResult();
                httpResult.setStatusCode(statusLine.getStatusCode());
                ContentType contentType = ContentType.getOrDefault(httpEntity);
                httpResult.setContentType(contentType.toString());
                boolean isTextType = isTextType(contentType);
                httpResult.setTextType(isTextType);
                if (isTextType) {
                    httpResult.setStringContent(EntityUtils.toString(httpEntity));
                } else {
                    httpResult.setByteArrayContent(EntityUtils.toByteArray(httpEntity));
                }
                httpResult.setHeaders(httpResponse.getAllHeaders());

                return httpResult;
            }
        };
        return responseHandler;
    }

    /**
     * 组装Get请求的请求参数
     * @param parameters 参数信息集合
     */
    private static List<NameValuePair> assemblyParameter(Map<String, String> parameters) {
        List<NameValuePair> allParameter = new ArrayList<>();
        if (parameters != null && !parameters.isEmpty()) {
            for (String name : parameters.keySet()) {
                NameValuePair parameter = new BasicNameValuePair(name, parameters.get(name));
                allParameter.add(parameter);
            }
        }
        return allParameter;
    }

    /**
     * 组装Post请求的Form请求体
     * @param parameters 请求的表单参数
     * @param charset 请求参数的字符编码
     */
    private static UrlEncodedFormEntity assemblyFormEntity(Map<String, String> parameters, String charset) {
        List<NameValuePair> formParameters = assemblyParameter(parameters);
        UrlEncodedFormEntity formEntity = null;
        try {
            if (charset != null) {
                formEntity = new UrlEncodedFormEntity(formParameters, charset);
            } else {
                formEntity = new UrlEncodedFormEntity(formParameters);
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return formEntity;
    }

    /**
     * 组装Post请求的Json请求体
     * @param jsonData 请求的Json数据
     * @param charset 请求参数的字符编码
     */
    private static StringEntity assemblyStringEntity(String jsonData, String charset) {
        /**
         * jsonData不能为null和"",否则无法创建StringEntity。
         * Json类型的请求体,必须传一个不为null的StringEntity给服务端。
         * 如果jsonData为null或""时,则进行特殊处理。
         */
        if (jsonData == null || jsonData.equals("")) {
            jsonData = "{}";
        }
        StringEntity stringEntity = new StringEntity(jsonData, ContentType.APPLICATION_JSON);
        if (charset != null) {
            stringEntity.setContentEncoding(charset);
        }
        return stringEntity;
    }

    /**
     * 组装Cookie
     * @param cookies 所有的Cookie数据
     */
    private static String assemblyCookie(Cookie[] cookies) {
        StringBuilder sb = new StringBuilder();
        if (cookies != null) {
            for(Cookie cookie : cookies) {
                sb.append(cookie.getName()).append("=").append(cookie.getValue()).append(";");
            }
        }
        return sb.toString();
    }

    /**
     * 判断响应的内容是否是文本类型
     * @param contentType 响应内容的类型
     */
    private static boolean isTextType(ContentType contentType) {
        if (contentType == null) {
            throw new RuntimeException("ContentType is null");
        }
        if (contentType.getMimeType().startsWith("text")) {
            return true;
        } else if (contentType.getMimeType().startsWith("image")) {
            return false;
        } else if (contentType.getMimeType().startsWith("application")) {
            if (contentType.getMimeType().contains("json") || contentType.getMimeType().contains("xml")) {
                return true;
            } else {
                return false;
            }
        } else if (contentType.getMimeType().startsWith("multipart")) {
            return false;
        } else {
            return true;
        }
    }




}
实体对象:
/**
 * @descriptions:
 * @author: [email protected]
 * @date: 2024/1/29 19:19
 * @version: 1.0
 */
@Data
public class HttpResult {
    /**
     * 响应的Header信息
     */
    private Header[] headers;

    /**
     * 响应状态码
     */
    private int statusCode;

    /**
     * 响应内容的类型
     */
    private String contentType;

    /**
     * 响应的内容是否是文本类型
     */
    private boolean isTextType;

    /**
     * 响应的内容(字符串形式)
     */
    private String stringContent;

    /**
     * 响应的内容(字节数组形式)
     */
    private byte[] byteArrayContent;

}

代码调用示例:

public static boolean valid(String createStaff,String role){
        HttpHeaders headers = getHeaders();
        JSONObject obj = new JSONObject();
        obj.put("name", "");
        obj.put("code", "");
        obj.put("phone", "");
        boolean isCustomerManager = false;
        HttpResult httpResult = HttpClientUtil.sendPostJson(hr_nbr_line, String.valueOf(obj), headers(), "UTF-8");
        String stringContent = httpResult.getStringContent();
        if (StringUtil.isValid(stringContent)) {
            JSONObject jsonObject = JSONObject.parseObject(stringContent);
            if (stringContent.contains(role)) {
                isCustomerManager = true;
            }
        }
        return isCustomerManager;
    }

该处使用的url网络请求的数据。

总结

提示:这里对文章进行总结:

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/MircoO/article/details/137881359

智能推荐

div内容超出容器宽度,超出显示省略号且鼠标悬浮显示全部内容_div设置省略号-程序员宅基地

文章浏览阅读946次,点赞8次,收藏10次。div内容超出容器宽度,超出部分显示省略号且鼠标悬浮显示全部内容_div设置省略号

Python类的重写和私有变量_重写方法其中的self变量怎么写-程序员宅基地

文章浏览阅读293次。1)类的重写# 如果子类想实现父类构造器中的方法,然后自己再写自己特殊的方法,便需要调用父类的__init__()方法class parent(object): # 定义父类的时候,一定要写继承object类,否则会报错 name = 'parent' sex = 'F' def __init__(self,address,age): self._重写方法其中的self变量怎么写

「Python」提取json数据为txt格式成功_python接口返回json数据是text格式-程序员宅基地

文章浏览阅读3k次,点赞2次,收藏10次。步骤1、你要检查json文件利用专门的解析json文件的网站校验进行https://www.sojson.com/2、不符合JSON语法格式的会报错,这时需要修改,直到正确3、Python读取一、JSON 语法规则数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组举例问题:它报错说逗号有问题,其实不是,问题出在缺少中括号。在最外层补充中括号,JSON文件就没问题了。二、Python读取json数据完整正确的代码:import jsonfile=r'中国合作t_python接口返回json数据是text格式

编码规范_源代码 编码规范 调研表-程序员宅基地

文章浏览阅读924次。1.4.B 编码规范——如何写出简洁优美的代码 下面是来自两位C语言程序员的实现相同功能的两段代码: l 月薪1000元的程序员的代码: #include int main() { FILE *Wenjian; char Str[100]; Wenjian = fopen("test.txt","w"); do_源代码 编码规范 调研表

xcrun simctl_xcrun simctl list 不显示device-程序员宅基地

文章浏览阅读665次。当我们执行xcrun simctl --help的时候,命令行显示xcrun simctl 的帮助信息,如下面内容,代码我们仔细分析学习一下使用方式:usage: simctl [--set <path>] [--profiles <path>] <subcommand> ...**用处:**通过命令行来操作模拟器,simctl提供很多子命令,让我们根据自己的需要随机选择,但是使用子命令的时候需要指定设备,也就是在在子命令后面追加 参数,参数不同代表执行的模拟器不_xcrun simctl list 不显示device

golang——随机数(math/rand包与crypto/rand包)-程序员宅基地

文章浏览阅读1.5k次。1、math/rand 包1.1、math/rand 包实现了伪随机数生成器1.2、主要方法(1)func Seed(seed int64)设置随机种子,不设置则默认Seed(1)(2)func Int() int返回一个非负的伪随机int值(3)func Int31() int32返回一个int32类型的非负的31位伪随机数(4)func Int63() in..._use of weak random number generator (math/rand instead of crypto/rand)

随便推点

解决‘error_code‘: 110, ‘error_msg‘: ‘Access token invalid or no longer valid(百度智能云使用方法)-程序员宅基地

文章浏览阅读1.2w次,点赞2次,收藏6次。解决’error_code’: 110, ‘error_msg’: 'Access token invalid or no longer valid(百度智能云使用方法)出现上述错误,是因为没有将例子中的access token的结果进行正确替换。具体做法如下:搜索百度智能云,注册登录以车牌识别为例:产品>汽车场景文字识别>立即使用>创建应用(归属选个人,免费)>查看详细信息(生成AD AK SK,将其复制)>使用方式>API文档获取accrss token_access token invalid or no longer valid

AES加密_aes加密 csdn-程序员宅基地

文章浏览阅读339次,点赞5次,收藏10次。密钥交换算法是指在不安全的通道上,通过某种算法交换一个密钥,常用的有Diffie-Hellman(DH)算法、椭圆曲线Diffie-Hellman(ECDH)算法等。消息摘要算法是一种单向加密算法,将任意长度的数据转换成固定长度的输出,常用的有MD5、SHA-1、SHA-2等。数字签名算法是将消息或数据进行哈希计算,然后用私钥签名,验证签名时使用公钥进行验证,常用的有RSA、DSA等。非对称加密算法使用一对密钥(公钥和私钥)对数据进行加密和解密,常用的有RSA、DSA、ECC等。3、确保数据的完整性。_aes加密 csdn

电脑C盘缓存清理全攻略:手把手教你如何安全有效地释放系统空间_qindows清理c盘最终版-程序员宅基地

文章浏览阅读561次,点赞3次,收藏3次。随着计算机使用时间的增长,C盘(系统盘)中的临时文件、系统缓存和日志等数据会逐渐累积,占用大量磁盘空间,导致系统运行速度减慢。定期对C盘进行缓存清理是保持系统健康与高效的重要维护工作。本文将详细介绍如何安全且有效地清理C盘中的各类缓存,帮助用户释放宝贵的存储资源。_qindows清理c盘最终版

python中怎么获取js的输出值_使用Python中的BeautifulSoup在HTML源代码中获取JS var值(Get JS var value in HTML source using Be...-程序员宅基地

文章浏览阅读1.2k次。使用Python中的BeautifulSoup在HTML源代码中获取JS var值(Get JS var value in HTML source using BeautifulSoup in Python)我正在尝试使用BeautifulSoup从HTML源代码中获取JavaScript var值。例如我有:[other code]var my = 'hello';var name = 'hi'..._python 取得js返回值

LVGL 移植记录(2)_keil5编译lvgl失败-程序员宅基地

文章浏览阅读1.9k次,点赞2次,收藏11次。准备代码之前clone下来的3份代码说明如下修改lv_conf.h和lv_ex_conf.h1.把lvgl目录下lv_conf_template.h和lv_examples目录下lv_ex_conf_template.h复制到如下路径并去掉文件名的_template2.把这2个文件中的#if 0改成#if 1lv_conf.h是对lvgl组件进行配置lv_ex_conf.h是对lvgl提供的例子进行配置,不是很重要其中lv_conf.h需要配置如下设置屏幕尺寸#define LV_HO_keil5编译lvgl失败

(二)Go Makes Things Simple_matlab出现file format not recognized collect2.exe: e-程序员宅基地

文章浏览阅读351次。GO web_matlab出现file format not recognized collect2.exe: error: ld returned 1 exit status