引言

在现代应用程序开发中,网络请求是必不可少的功能之一。无论是访问第三方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.pswp.cn/bicheng/91241.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/91241.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/91241.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Spring Boot的装饰工程管理系统(源码+论文)

一、 开发环境与技术 本章节对开发装饰工程管理系统------项目立项子系统需要搭建的开发环境&#xff0c;以及装饰工程管理系统------项目立项子系统开发中使用的编程技术等进行阐述。 1 开发环境 工具/环境描述操作系统Windows 10/11 或 Linux&#xff08;如 Ubuntu&#x…

【WebGPU学习杂记】数学基础拾遗(2)变换矩阵中的齐次坐标推导与几何理解

今天打算开始 3D 数学基础的复习&#xff0c;本文假设你了解以下概念&#xff1a;一次多项式、矩阵、向量&#xff0c;基于以上拓展的概念 归一化、2&#xff5e;3阶矩阵的几何意义。几何意义结论 齐次坐标是对三维的人工的特定的升维&#xff0c;它是一个工具而已。图形学中常…

JS前端压缩算法——WWDHCAPOF-算法导论论文——东方仙盟算法

代码function customCompressString(input) {// 第一步&#xff1a;将字符串转换为ANSI码数组并乘以位置序号let resultArray Array.from(input).map((char, index) > {const ansiCode char.charCodeAt(0);return ansiCode * (index 东方仙盟); // 位置序号从1开始});// …

linux命令less的实际应用

less 是 Linux/Unix 中交互式文件查看神器&#xff0c;相比 more 和 cat&#xff0c;它支持自由导航、搜索、高亮等强大功能&#xff0c;尤其适合处理大文件或实时日志。以下是深度应用指南&#xff1a;​一、核心优势​less large_file.log # 秒开GB级文件&#xff08…

DAY31 整数矩阵及其运算

DAY31 整数矩阵及其运算 本次代码通过IntMatrix类封装了二维整数矩阵的核心操作&#xff0c;思路如下&#xff1a;数据封装→基础操作&#xff08;修改和获取元素、获取维度&#xff0c;toString返回字符串表示&#xff0c;getData返回内部数组引用&#xff09;→矩阵运算&…

飞桨深度学习环境搭建

一、安装 PyCharm PyCharm 官网下载页面 记得全部勾选。 二、安装 miniconda miniconda 官网下载页面 根据你的操作系统选择。 记得勾选前三个。 三、安装 CUDA 首先 nvidia-smi 查看支持最高的 CUDA 版本。 然后去 nvidia 官网下载 CUDA&#xff0c;选择适合你的版本。 …

MySQL 8.0 OCP 1Z0-908 题目解析(37)

题目146 Choose two. Which two are true about binary logs used in asynchronous replication? □ A) The master connects to the slave and initiates log transfer. □ B) They contain events that describe all queries run on the master. □ C) They contain events …

vue element 封装表单

背景&#xff1a; 在前端系统开发中&#xff0c;系统页面涉及到的表单组件比较多&#xff0c;所以进行了简单的封装。封装的包括一些Form表单组件&#xff0c;如下&#xff1a;input输入框、select下拉框、等 实现效果&#xff1a; 理论知识&#xff1a; 表单组件官方链接&…

flutter-完美解决键盘弹出遮挡输入框的问题

文章目录1. 前言2. 借助 Scaffold 的特性自动调整3. 使用 MediaQuery 精准控制抬升高度3.1. 底部抽屉内输入框的方案4. 注意事项5. 总结1. 前言 在 Flutter 的开发过程中&#xff0c;经常会碰到某一个页面有个 TextField 输入组件&#xff0c;点击的时候键盘会弹起来&#xff…

机器学习笔记(四)——聚类算法KNN、Kmeans、Dbscan

写在前面&#xff1a;写本系列(自用)的目的是回顾已经学过的知识、记录新学习的知识或是记录心得理解&#xff0c;方便自己以后快速复习&#xff0c;减少遗忘。概念部分大部分来自于机器学习菜鸟教程&#xff0c;公式部分也会参考机器学习书籍、阿里云天池。机器学习如果只啃概…

【C#】事务(进程 ID 64)与另一个进程被死锁在锁资源上,并且已被选作死锁牺牲品。请重新运行该事务。不能在具有唯一索引“XXX_Index”的对象“dbo.Test”中插入重复键的行。

&#x1f339;欢迎来到《小5讲堂》&#x1f339; &#x1f339;这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。&#x1f339; &#x1f339;温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01;&#…

LeetCode Hot 100 搜索二维矩阵

给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a;每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。示例…

python毕设高分案例:基于机器学习的抑郁症数据分析与预测系统,flask框架,算法包括XGboost模型、梯度提升树模型等

1 绪论 1.1 课题研究背景和意义 1.1.1 研究背景 在医疗行业不断发展的当下&#xff0c;数据量呈现出爆炸式增长&#xff0c;医学数据的复杂性和多样性也达到了前所未有的程度。电子病历系统记录了患者丰富的诊疗信息&#xff0c;医学影像技术如 CT、MRI 等生成海量的图像数据…

STM32与ADS1256多通道数据采样原理及控制程序

好的,使用 STM32 与 ADS1256 通信读取多通道电压是精密数据采集的常见方案。ADS1256 是一款高精度、24 位、8 通道(或差分 4 通道)的 ΔΣ ADC,非常适合需要高分辨率的应用(如传感器信号、医疗仪器等)。 以下是对整个过程的详细分析及基于 STM32 HAL 库的程序示例: 核…

Spring Boot 3.5.x 使用 SpringDoc 2 / Swagger3

这篇文章资料来自于网络&#xff0c;对部分知识整理&#xff0c;这里只是记录一下&#xff0c;仅供参考 为什么要用 Swagger Swagger 的核心思想是通过定义和描述 API 的规范、结构和交互方式&#xff0c;以提高 API 的可读性、可靠性和易用性&#xff0c;同时降低 API 开发的难…

@RefreshScope 核心原理深度解析:Spring Boot 的动态魔法

让我们通过全新的原理图解和代码级分析&#xff0c;揭开RefreshScope实现配置热更新的神秘面纱&#xff01;一、工作原理全景图&#xff08;优化版&#xff09; #mermaid-svg-50lhLlOFeSRIWnLn {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px…

万字详解——OSI七层模型:网络通信的完整架构解析

OSI七层模型&#xff1a;网络通信的完整架构解析OSI&#xff08;Open Systems Interconnection&#xff09;七层模型是计算机网络领域最基础、最权威的参考框架。它由国际标准化组织&#xff08;ISO&#xff09;于1984年提出&#xff0c;旨在为不同厂商、不同技术的网络设备和系…

一个人开发一个App(OpenApi)

为了少写代码&#xff0c;统一前后端的网络层&#xff0c;我使用了OpenApi设计restful接口。然后用openapi-generator来生成flutter的代码。生成go代码用的是oapi-codegen,它对go更友好一些。 我们直接在api.yml中设计接口&#xff0c;所有的返回值与请求者都提取到components里…

光伏气象监测系统:助力光伏发电的智慧大脑

光伏气象监测系统&#xff1a;助力光伏发电的智慧大脑 柏峰【BF-GFQX】在全球积极推动能源转型、大力倡导 “双碳” 目标的当下&#xff0c;光伏发电凭借其清洁、可再生的显著优势&#xff0c;宛如一颗冉冉升起的新星&#xff0c;在能源领域迅速崭露头角&#xff0c;得以广泛推…

SpringCloud01——项目演变、微服务远程调用三种方式、springcloud介绍、nacos注册中心

目录 一、项目架构演变过程 1、单体应用架构 2、垂直应用架构 3、分布式服务架构 4、流动计算架构&#xff08;SOA架构&#xff09; 5、微服务架构 二、如何实现微服务远程调用 1、HttpClient工具类&#xff08;springboot中&#xff09; 形式1&#xff1a;调用第三方…