使用WebClient发起网络请求

目录

1、导入对应的pom

2、编写WebClientUtil请求工具类

3、使用WebClientUtil发起请求


使用WebClient的优点:支持lambdas 的函数;支持更高的并发性和更少的硬件资源;支持同步和异步;支持流式传输。具体的使用方式如下:

1、导入对应的pom

https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-webflux
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-webflux -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId><version>3.2.4</version>
</dependency>

其中版本可以选择当前最新即可!

2、编写WebClientUtil请求工具类

(当然此步骤非必须,可以直接在需要发起请求的地方直接定义发起也可以)


import org.springframework.http.*;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientResponseException;
import reactor.core.publisher.Mono;import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;/*** Web 客户端实用程序** @author xjs* @date 2024/03/25*/
public class WebClientUtil {private static final WebClient WEB_CLIENT = WebClient.create();// 默认JSON格式//private static final WebClient WEB_CLIENT = WebClient.builder().defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).build();//==============================================================================================================================/*** 发起GET请求,支持Get parameter*/public static CompletableFuture<String> getParam(String url, HttpHeaders headers, MultiValueMap<String, String> queryParams) {return Mono.from(WEB_CLIENT.get().uri(uriBuilder -> uriBuilder.path(url).queryParams(queryParams).build()).headers(httpHeaders -> httpHeaders.putAll(headers))//.headers(h -> headers.forEach(h::add)).retrieve().onStatus(HttpStatus::isError, clientResponse -> Mono.error(new RuntimeException("HTTP error status: " + clientResponse.statusCode()))).bodyToMono(String.class)).onErrorResume(error -> Mono.just("Error: " + error.getMessage())) // 如果有错误,返回错误信息.toFuture();}/*** 发起GET请求,支持Get parameter* 可以用*/public static CompletableFuture<String> getNoParam(String url, HttpHeaders headers) {return Mono.from(WEB_CLIENT.get().uri(url).headers(httpHeaders -> httpHeaders.putAll(headers))//.headers(h -> headers.forEach(h::add)).retrieve().onStatus(HttpStatus::isError, clientResponse -> Mono.error(new RuntimeException("HTTP error status: " + clientResponse.statusCode()))).bodyToMono(String.class)).onErrorResume(error -> Mono.just("Error: " + error.getMessage())) // 如果有错误,返回错误信息.toFuture();}/*** 发起POST请求,支持JSON body*/public static CompletableFuture<String> postJson2(String url, Object body, HashMap<String, String> headers) {logRequest();return Mono.from(WEB_CLIENT.post().uri(url).contentType(MediaType.APPLICATION_JSON).headers(h -> headers.forEach(h::add)).bodyValue(body).retrieve().onStatus(HttpStatus::isError, clientResponse -> Mono.error(new RuntimeException("HTTP error status: " + clientResponse.statusCode()))).bodyToMono(String.class)).onErrorResume(error -> Mono.just("Error: " + error.getMessage())) // 如果有错误,返回错误信息.toFuture();}/*** 发起POST请求,支持表单数据*/public static CompletableFuture<String> postForm(String url, MultiValueMap<String, String> formData, Map<String, String> headers) {return Mono.from(WEB_CLIENT.post().uri(url).headers(h -> headers.forEach(h::add)).contentType(MediaType.APPLICATION_FORM_URLENCODED).body(BodyInserters.fromFormData(formData)).retrieve().bodyToMono(String.class)).toFuture();}//===========方法2======================================================================================================public static <T> Mono<ResponseEntity<T>> sendRequest(String url, HttpMethod method, HashMap<String, String> headers, Object requestBody, Class<T> responseType) {return WEB_CLIENT.method(method).uri(url).headers(h -> headers.forEach(h::add)).body(BodyInserters.fromValue(requestBody)).retrieve().toEntity(responseType);}public static CompletableFuture<String> postJson2(String url, Object body, HashMap<String, String> headers) {return sendRequest(url, HttpMethod.POST, headers, body, String.class).doOnError(error -> System.err.println("An error occurred: " + error.getMessage())).filter(entity -> entity.getStatusCode().is2xxSuccessful()) // 检查状态码是否成功.mapNotNull(ResponseEntity::getBody).onErrorResume(error -> Mono.just("Error: " + error.getMessage())) // 如果有错误,返回错误信息.toFuture();}//===========方法3============================================================================================================================================================private String baseUrl = "http://192.168.31.118:8091";WebClient webClient = WebClient.builder().baseUrl(baseUrl).defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)// 使用了ExchangeStrategies来限制默认的解码器缓冲区的大小。这有助于避免处理大型响应时的内存问题。.exchangeStrategies(ExchangeStrategies.builder().codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024)).build()).build();/*** put 请求** @param url         网址* @param requestBody 请求正文* @return {@link Mono}<{@link String}>*/public Mono<String> putRequest(String url, Object requestBody) {return webClient.put().uri(url).body(BodyInserters.fromValue(requestBody)).retrieve().bodyToMono(String.class);}/*** 删除请求** @param url 网址* @return {@link Mono}<{@link String}>*/public Mono<String> deleteRequest(String url) {return webClient.delete().uri(url).retrieve().bodyToMono(String.class);}}

3、使用WebClientUtil发起请求

    /*** 获取配置中的请求地址*/@Value("${url.baseUrl}")private String baseUrl;//发起POST请求@PostMapping("/postRequest")public Object postRequest(@RequestBody RequestParms requestParms) {// 设置请求头信息HashMap<String, String> headers = new HashMap<>();headers.put("Content-Type", "application/json");CompletableFuture<String> postResponse = WebClientUtil.postJson(baseUrl, requestParms, headers);// 异步处理响应postResponse.thenAccept(response -> {log.info("response: {}", response);if (response.contains("code")) {try {JSONObject postResponseJson = JSONObject.parseObject(response);int statusCode = postResponseJson.getIntValue("code");log.info("statusCode = " + statusCode);JSONArray data = postResponseJson.getJSONArray("data");log.info("data = " + data);} catch (Exception e) {log.info("Failed to parse JSON: " + e.getMessage());}} else {log.info("No 'code' field in the response: " + response);}});return postResponse;}//发起GET请求@GetMapping("/getRequest")public Object getRequest(RequestParms requestParms) {// 创建请求头HttpHeaders headers = new HttpHeaders();headers.add("Accept", "application/json, text/javascript, */*; q=0.01");headers.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36");// 创建请求参数MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();queryParams.add("code", requestParms.getCode());// 构建URL地址UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(url);uriBuilder.queryParams(queryParams);String newUrls = String.valueOf(uriBuilder.build().toUri());// 发送GET请求//CompletableFuture<String> getResponse = WebClientUtil.getParam(url, headers, queryParams);CompletableFuture<String> getResponse = WebClientUtil.getNoParam(newUrls, headers);getResponse.thenAccept(response -> {log.info("response: {}", response);if (response.contains("status")) {try {JSONObject postResponseJson = JSONObject.parseObject(response);String status = postResponseJson.getString("status");log.info("status = " + status);JSONObject data = postResponseJson.getJSONObject("result");log.info("data = " + data);} catch (Exception e) {log.info("Failed to parse JSON: " + e.getMessage());}} else {log.info("No 'code' field in the response: " + response);}});return getResponse;}

至此,就可以完成发网络请求了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/568460.html

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

相关文章

单片机入门到精通:一站式在线学习平台!

介绍&#xff1a;单片机&#xff0c;也称为微控制器&#xff08;MCU&#xff09;&#xff0c;是一种集成了中央处理器&#xff08;CPU&#xff09;、随机存储器&#xff08;RAM&#xff09;、只读存储器&#xff08;ROM&#xff09;以及输入/输出接口于单一芯片上的微型计算机。…

【数据库】SQL Server 2008 R2 安装过程

启动安装程序&#xff0c;点击setup&#xff0c;进入【SQLServer安装中心】 点击界面左侧的【安装】&#xff0c;然后点击右侧的【全新SQLServer独立安装或向现有安装添加功能】&#xff0c;进入【SQLServer2008R2安装程序】界面&#xff0c;如下图所示&#xff1a; 进入【安装…

SQL复习专题

请结合B站-技术蛋老师 视频学习 核心语法 一、增&#xff1a;数据库/表格 create create database 数据库名&#xff1b;#创建表&#xff08;列名类型&#xff09; mysql> create table eggs_record(-> id int,-> egg_name varchar(10),-> sold date-> ); 这…

hcip复习总结2(广域网与OSPF)

数据链路层面&#xff1a; 针对不同的物理链路定义不同的封装 局域网封装&#xff1a; Ethernet 2 &#xff08; TCP/IP &#xff09; &#xff0c; IEEE802.3 &#xff08; OSI &#xff09; 广域网封装&#xff1a; PPP HDLC FR ATM HDLC &#xff1a; 高级数据链路控制协…

WPF —— Expander折叠栏 、菜单标签 menu

Expander 1 &#xff1a;Expander折叠栏 简介 Expander控件有一个箭头按钮。单击箭头时&#xff0c;Expander中的子元素将显示或隐藏。箭头“展开”控件&#xff0c;使其子控件可见。 2 &#xff1a;Expander常用的属性 IsEnabled 默认是打开或者折叠起来&#xff0c;true就…

漏洞挖掘 | EDU小通用漏洞分享

1.信息搜集 首先就是信息搜集&#xff0c;挖edu没账号怎么办呢&#xff1f;sg妹子不行&#xff0c;咱就找能自己注册的站。 Hunter&#xff1a;web.title”XX大学”&&web.body”注册” Fofa&#xff1a;host”.edu.cn” && body”注册” && country”…

Java基础内容汇总(上)

目录 一、基础二、数组三、类和对象四、面向对象特征之一&#xff1a;封装与隐藏4.1、构造器(构造方法)4.2、this 的使用4.3、关键字—import 五、继承5.1、方法的重写(override/overwrite)5.2、关键字&#xff1a;super 六、多态6.1、操作符与equals方法6.2、toString的使用6.…

C++ 3.25作业

1、定义自己的命名空间&#xff0c;其中有string类型的变量&#xff0c;再定义两个函数&#xff0c;一个函数完成字符串的输入&#xff0c;一个函数完成求字符串长度&#xff0c;再定义一个全局函数完成对该字符串的反转 #include <iostream>using namespace std;namesp…

C/C++语言相关常见面试题总结

目录 const关键字的作用 volatile 关键字 #define和const有什么区别 decltype和auto的区别 extern 关键字的作用 如何避免野指针 C/C中的类型转换以及使用场景 什么是RTTI&#xff1f;其原理是什么&#xff1f; RTTI 的原理&#xff1a; C中引用和指针的区别 C11用过…

PyCharm环境下Git与Gitee联动:本地与远程仓库操作实战及常见问题解决方案

写在前面&#xff1a;本博客仅作记录学习之用&#xff0c;部分图片来自网络&#xff0c;如需引用请注明出处&#xff0c;同时如有侵犯您的权益&#xff0c;请联系删除&#xff01; 文章目录 前言下载及安装GitGit的使用设置用户签名设置用户安全目录Git基本操作Git实操操作 Pyc…

libVLC 视频缩放

libvlc是一个常用的开源多媒体框架&#xff0c;它可以用来播放和处理各种类型的音频和视频文件。如果想要缩放视频&#xff0c;可以通过libvlc提供的API来实现。 //设置视频的缩放比例。 libvlc_video_set_scale() 以下是如何使用 libVLC 设置视频缩放的基本步骤&#xff1a;…