当前位置: 首页 > news >正文

java网络请求工具类HttpUtils

引言

在现代应用程序开发中,网络请求是必不可少的功能之一。无论是访问第三方API、微服务之间的通信,还是请求远程数据,都需要通过HTTP协议实现。

在Java中,java.net.HttpURLConnection、Apache的HttpClient库以及OkHttp等库提供了丰富的HTTP请求功能,但这些API有时需要较多的样板代码,因此封装一个通用的网络请求工具类(如HttpUtils或HttpClientUtils)可以简化开发流程,提高效率。


HttpUtils 工具类设计

HttpUtils 是一个封装了常用HTTP请求操作的工具类,基于 Apache HttpClient 实现。这个工具类支持 GET、POST、PUT、DELETE 等常见请求方法,并提供了请求头设置、参数传递、响应处理、超时设置等功能。

以下是 HttpUtils 工具类的主要功能:

  • 发送 GET 请求:用于从服务器获取资源。
  • 发送 POST 请求:用于向服务器提交数据。
  • 发送 PUT 请求:用于更新服务器上的资源。
  • 发送 DELETE 请求:用于删除服务器上的资源。
  • 发送 PATCH 请求:对资源进行部分更新。它的主要特点是只更新资源的部分属性,而不是像PUT那样替换整个资源
  • 设置请求头:支持自定义请求头,如Content-Type、Authorization等。
  • 设置cookies
  • 超时设置:支持连接超时和读取超时的设置。

HttpUtils 工具类的实现

import com.alibaba.fastjson2.JSONObject;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import org.apache.http.impl.client.HttpClients;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;public class HttpUtils {private static final RestTemplate REST_TEMPLATE;static {HttpComponentsClientHttpRequestFactory factory =new HttpComponentsClientHttpRequestFactory(HttpClients.custom().setMaxConnTotal(512)    // 设置整个连接池的最大连接数为 512.setMaxConnPerRoute(32)  // 设置每个路由(如相同域名)的最大连接数为 32.build());// 表示建立TCP连接的超时时间为5000毫秒(5秒)。// 若超过此时限仍未完成连接建立,将抛出ConnectTimeoutException。该设置适用于网络延迟较高或目标服务不可达的场景‌factory.setConnectTimeout(5000);// 定义从服务器读取数据的超时时间为10000毫秒(10秒)。// 若服务器在此时限内未返回完整响应数据,将触发SocketTimeoutException。适用于处理响应较慢的API接口‌factory.setReadTimeout(10000);REST_TEMPLATE = new RestTemplate(factory);}// GET请求方法public static String executeGet(String url, JSONObject params,String contentType,Map<String, String> cookies) {return executeRequest(url, params, HttpMethod.GET.name(), contentType,cookies);}// POST请求方法public static String executePost(String url, JSONObject params,String contentType,Map<String, String> cookies) {return executeRequest(url, params, HttpMethod.POST.name(), contentType,cookies);}// PUT请求方法public static String executePut(String url, JSONObject params, String contentType,Map<String, String> cookies) {return executeRequest(url, params, HttpMethod.PUT.name(), contentType,cookies);}// DELETE请求方法public static String executeDelete(String url, JSONObject params, String contentType,Map<String, String> cookies) {return executeRequest(url, params, HttpMethod.DELETE.name(), contentType,cookies);}// PATCH请求方法public static String executePatch(String url, JSONObject params, String contentType,Map<String, String> cookies) {return executeRequest(url, params, HttpMethod.PATCH.name(), contentType,cookies);}// 原始完整参数方法保留private static String executeRequest(String url, JSONObject params,String method, String contentType,Map<String, String> cookies) {try {// 创建URL构建器UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromHttpUrl(url);// 处理GET请求的参数if (HttpMethod.GET.name().equalsIgnoreCase(method)) {// 将每个参数添加到URL查询字符串for (Map.Entry<String, Object> param : params.entrySet()) {urlBuilder.queryParam(param.getKey(), param.getValue());}// 构建最终URL并编码特殊字符url = urlBuilder.build().encode(StandardCharsets.UTF_8).toUriString();}HttpHeaders headers = new HttpHeaders();//设置cookiesif (cookies != null) {addCookies(headers, cookies);}//设置请求体Object requestBody = prepareRequestBody(params, method, contentType, headers);//开始调用ResponseEntity<String> response = REST_TEMPLATE.exchange(url,Objects.requireNonNull(HttpMethod.resolve(method.toUpperCase())),new HttpEntity<>(requestBody, headers),String.class);if (!response.getStatusCode().is2xxSuccessful()) {throw new RuntimeException("HTTP请求失败: " + response.getStatusCode());}return response.getBody();} catch (Exception e) {throw new RuntimeException("HTTP请求异常", e);}}private static Object prepareRequestBody(JSONObject params, String method,String contentType, HttpHeaders headers) {if (HttpMethod.GET.name().equalsIgnoreCase(method)) return null;switch(contentType.toLowerCase()) {case "application/json":headers.setContentType(MediaType.APPLICATION_JSON);return params;case "application/x-www-form-urlencoded":headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);return buildFormData(params);default:throw new IllegalArgumentException("不支持的Content-Type: " + contentType);}}private static MultiValueMap<String, String> buildFormData(JSONObject params) {MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();params.forEach((k, v) -> formData.add(k, v.toString()));return formData;}public static void addCookies(HttpHeaders headers, Map<String, String> cookies) {if (cookies != null && !cookies.isEmpty()) {List<String> cookieList = new ArrayList<>();cookies.forEach((k, v) -> cookieList.add(k + "=" + v));headers.put(HttpHeaders.COOKIE, cookieList);}}}

这是一个基于Spring框架的HTTP请求工具类,主要使用RestTemplate和Apache HttpClient实现HTTP通信功能。以下是对该工具类的详细解析:‌

1‌、RestTemplate初始化

通过HttpComponentsClientHttpRequestFactory配置底层HTTP客户端,关键参数包括:‌

  • setMaxConnTotal(512):全局最大连接数限制‌
  • setMaxConnPerRoute(32):单域名最大连接数限制‌
  • setConnectTimeout(5000):TCP连接超时时间(5秒)
  • setReadTimeout(10000):数据读取超时时间(10秒)

2、HTTP方法封装

  • 支持GET/POST/PUT/DELETE/PATCH方法,统一调用executeRequest处理‌
  • 通过HttpMethod.resolve()动态解析请求类型,避免硬编码‌

3、参数处理

  • GET请求‌:参数拼接至URL,自动进行UTF-8编码‌
  • POST/PUT等请求‌:根据contentType处理请求体:x-www-form-urlencoded:转换为MultiValueMap表单数据‌。application/json:直接传递JSON对象‌

4、Cookie管理

  • addCookies()方法将Map格式的Cookie转换为HTTP头格式(key=value)

5、异常处理

  • 统一捕获异常并包装为RuntimeException
  • 检查响应状态码,非2xx响应抛出明确异常‌

测试用例参考

我们启动本地xxl-job,然后访问用户列表查询页面

 相关请求参数如下

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.utils.HttpUtils;
import lombok.Data;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** Http远程调用测试*/
public class TestHttp {// 新增嵌套实体类@Dataprivate static class UserDetail {private Integer id;private String username;private String password;}@Testpublic void testHttp() {try {//模拟请求参数JSONObject params = new JSONObject();params.put("role", -1);params.put("start",0);params.put("length",10);//模拟请求cookiesMap<String, String> cookies = new HashMap<>();cookies.put("XXL_JOB_LOGIN_IDENTITY", "7b226964223a312c22757365726e616d65223a2261646d696e222c2270617373776f7264223a226531306164633339343962613539616262653536653035376632306638383365222c22726f6c65223a312c227065726d697373696f6e223a6e756c6c7d");//开始远程调用String str = HttpUtils.executePost("http://localhost:9000/xxl-job-admin/user/pageList",params,MediaType.APPLICATION_FORM_URLENCODED_VALUE,cookies);//解析反参System.out.println(str);JSONObject jsonObject = JSONObject.parseObject(str);JSONArray dataArray = jsonObject.getJSONArray("data");List<UserDetail> list = dataArray.toList(UserDetail.class);System.out.println(list);}catch (Exception e){e.printStackTrace();}}
}

最后成功返回数据

http://www.dtcms.com/a/299769.html

相关文章:

  • 如何查找php配置文件php.ini
  • URL与URI:互联网世界的“门牌号“与“身份证“
  • 【机器学习深度学习】模型微调:多久才算微调完成?——如何判断微调收敛,何时终止训练
  • Linux库——库的制作和原理(2)_库的原理
  • 微软中国高级架构师步绍鹏受邀为第十四届PMO大会演讲嘉宾
  • gig-gitignore工具实战开发(五):gig add完善
  • 单片机中的三极管
  • write`系统调用
  • 字节跳动正式开源AI智能体开发平台Coze
  • LeetCode——1957. 删除字符使字符串变好
  • 1.安装anaconda详细步骤(含安装截图)
  • Typecho插件开发实战:构建专业级访问日志系统
  • ESP32-idf学习(五)esp32C3移植lvgl①
  • 贝叶斯决策论
  • Spring AI MCP 客户端
  • Django+celery异步:拿来即用,可移植性高
  • SSSM框架相关问题总结
  • 拒绝SQL恐惧:用Python+pyqt打造Excel数据库查询系统
  • [Java恶补day47] 整理模板·考点十【二叉树层序遍历】
  • 快速入门Linux操作系统(一)
  • LeetCode 面试经典 150_数组/字符串_删除有序数组中的重复项(3_26_C++_简单)
  • RabbitMQ--消息丢失问题及解决
  • 是德科技 | AI上车后,这条“高速公路”如何畅通?
  • 如何高效合并音视频文件(时间短消耗资源少)(二)
  • 计网-TCP可靠传输
  • 周末小游戏推荐,离线也能畅玩
  • 阿里云对象存储OSS(Object Storage Service)全面解析
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘ipython’问题
  • 【计算机组成原理】第一章:计算机系统概述
  • GO 从入门到精通