目录
1、导入对应的pom
2、编写WebClientUtil请求工具类
3、使用WebClientUtil发起请求
使用WebClient的优点:支持lambdas 的函数;支持更高的并发性和更少的硬件资源;支持同步和异步;支持流式传输。具体的使用方式如下:
1、导入对应的pom
![](https://img-blog.csdnimg.cn/direct/ead85f347c684f3db8579df0dfa48522.png)
<!-- 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;}
至此,就可以完成发网络请求了!