WebClient 同步、异步调用实现对比

2024-03-22 16:28

本文主要是介绍WebClient 同步、异步调用实现对比,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、概述
  • 二、pom依赖
  • 三、代码结构
  • 四、源码传送
    • 1、异步代码
    • 2、同步代码
    • 3、完整代码

一、概述

WebClient是Spring WebFlux模块提供的一个非阻塞的基于响应式编程的进行Http请求的客户端工具,从Spring5.0开始WebClient作为RestTemplete的替代品,有更好的响应式能力,支持异步调用,可以在Spring项目中实现网络请求。

二、pom依赖

		<dependency><groupId>org.springframework</groupId><artifactId>spring-webflux</artifactId><version>5.2.3.RELEASE</version></dependency><dependency><groupId>io.projectreactor.netty</groupId><artifactId>reactor-netty</artifactId><version>0.9.4.RELEASE</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j-impl</artifactId><version>2.12.1</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.13.0</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.10</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.5</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version><scope>provided</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>

三、代码结构

在这里插入图片描述

图片请手工放入 src\test\resources\123.jpg
在这里插入图片描述
单元测试
在这里插入图片描述

四、源码传送

1、异步代码

import java.awt.Desktop;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;import javax.imageio.ImageIO;import org.apache.commons.lang3.RandomUtils;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;import com.fly.http.bean.ImageShowDialog;
import com.fly.http.bean.JsonBeanUtils;
import com.fly.http.bean.SearchReq;import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;/*** http请求WebClient异步调用实现*/
@Slf4j
public class WebClientAsyncTest
{private WebClient webClient = WebClient.builder().codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(-1)).build();private void openImage(Resource resource){try{new ImageShowDialog(ImageIO.read(resource.getInputStream()));}catch (IOException e){log.error(e.getMessage(), e);}}@BeforeClasspublic static void init(){new File("download").mkdirs();}/*** WebClient异步调用* * @throws IOException* @throws InterruptedException*/@Testpublic void testDownFile()throws IOException, InterruptedException{Mono<Resource> mono = webClient.get().uri("https://00fly.online/upload/urls.txt").accept(MediaType.IMAGE_JPEG).exchange().doOnSuccess(clientResponse -> log.info("----- headers: {}", clientResponse.headers())).doOnSuccess(clientResponse -> log.info("----- statusCode: {}", clientResponse.statusCode())).flatMap(clientResponse -> clientResponse.bodyToMono(Resource.class));// 保存到本地mono.subscribe(resource -> {try{FileCopyUtils.copy(resource.getInputStream(), new FileOutputStream("download/urls.txt"));}catch (IOException e){log.error(e.getMessage(), e);}});TimeUnit.SECONDS.sleep(2);}/*** WebClient异步调用* * @throws IOException* @throws InterruptedException*/@Testpublic void testDownImg001()throws IOException, InterruptedException{Mono<Resource> mono = webClient.get().uri("https://00fly.online/upload/2019/02/201902262129360274AKuFZcUfip.jpg").accept(MediaType.IMAGE_JPEG).retrieve() // 获取响应体.bodyToMono(Resource.class);mono.subscribe(resource -> openImage(resource));TimeUnit.SECONDS.sleep(10);}/*** WebClient异步调用* * @throws IOException* @throws InterruptedException*/@Testpublic void testDownImg002()throws IOException, InterruptedException{Mono<Resource> mono = webClient.get().uri("https://00fly.online/upload/2019/02/201902262129360274AKuFZcUfip.jpg").accept(MediaType.IMAGE_JPEG).retrieve() // 获取响应体.bodyToMono(Resource.class);// 保存到本地mono.subscribe(resource -> {try{File dest = new File(String.format("download/img_%s.jpg", System.currentTimeMillis()));FileCopyUtils.copy(resource.getInputStream(), new FileOutputStream(dest));if (Desktop.isDesktopSupported()){Desktop.getDesktop().open(dest.getParentFile());}}catch (IOException e){log.error(e.getMessage(), e);}});TimeUnit.SECONDS.sleep(2);}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testExchange001()throws InterruptedException{// getMultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("q1", "java");params.add("q2", "python");Mono<ClientResponse> monoGet = webClient.get().uri(uriBuilder -> uriBuilder.scheme("https").host("httpbin.org").path("/get").queryParams(params) // 等价 queryParam("q1", "java").queryParam("q2", "python").build()).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange();monoGet.subscribe(clientResponse -> {log.info("----- headers: {}", clientResponse.headers());log.info("----- statusCode: {}", clientResponse.statusCode());clientResponse.bodyToMono(String.class).subscribe(body -> log.info("----- reponse: {}", body));});TimeUnit.SECONDS.sleep(2);}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testExchange002()throws InterruptedException{// getMono<ClientResponse> monoGet = webClient.get().uri(uriBuilder -> uriBuilder.scheme("https").host("httpbin.org").path("/get").queryParam("q1", "java").queryParam("q2", "python").build()).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange();monoGet.subscribe(clientResponse -> {log.info("----- headers: {}", clientResponse.headers());log.info("----- statusCode: {}", clientResponse.statusCode());clientResponse.bodyToMono(String.class).subscribe(body -> log.info("----- reponse: {}", body));});// formData postMultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("q1", "java");params.add("q2", "python");Mono<ClientResponse> monoPost = webClient.post().uri("https://httpbin.org/post").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromFormData(params)) // 设置formData,等价 BodyInserters.fromFormData("q1", "java").with("q2", "python").exchange();monoPost.subscribe(clientResponse -> {log.info("----- headers: {}", clientResponse.headers());log.info("----- statusCode: {}", clientResponse.statusCode());clientResponse.bodyToMono(String.class).subscribe(body -> log.info("----- reponse: {}", body));});TimeUnit.SECONDS.sleep(2);}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testFormDataPost()throws InterruptedException{MultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("q1", "java");params.add("q2", "python");Mono<String> mono = webClient.post().uri("https://httpbin.org/post").contentType(MediaType.APPLICATION_FORM_URLENCODED).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromFormData(params)) // 设置formData,等价 BodyInserters.fromFormData("q1", "java").with("q2", "python").retrieve() // 获取响应体.bodyToMono(String.class); // 响应数据类型转换mono.subscribe(body -> log.info("----- reponse: {}", body));TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testGet001()throws InterruptedException{Mono<String> mono = webClient.get().uri("https://httpbin.org/{method}", "get") // {任意命名}.acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).retrieve().bodyToMono(String.class);mono.subscribe(body -> log.info("----- reponse: {}", body));TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testGet002()throws InterruptedException{Mono<ClientResponse> mono = webClient.get().uri("https://httpbin.org/get").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange();mono.subscribe(reponse -> {log.info("----- headers: {}", reponse.headers());log.info("----- statusCode: {}", reponse.statusCode());reponse.bodyToMono(String.class).subscribe(body -> log.info("----- reponse: {}", body));});TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testGet003()throws InterruptedException{Mono<String> mono = webClient.get().uri("https://httpbin.org/get").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange().doOnSuccess(clientResponse -> log.info("----- headers: {}", clientResponse.headers())).doOnSuccess(clientResponse -> log.info("----- statusCode: {}", clientResponse.statusCode())).flatMap(clientResponse -> clientResponse.bodyToMono(String.class));mono.subscribe(body -> log.info("----- reponse: {}", body));TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用, https://httpbin.org/get?q=java* * @throws InterruptedException*/@Testpublic void testGet004()throws InterruptedException{MultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("q", "java");String uri = UriComponentsBuilder.fromUriString("https://httpbin.org/get").queryParams(params).toUriString();// 注意比较// uri = UriComponentsBuilder.fromUriString("https://httpbin.org/get").queryParam("q", "java", "python").toUriString();// uri = UriComponentsBuilder.fromUriString("https://httpbin.org/get").queryParam("q1", "java").queryParam("q2", "python").toUriString();Mono<String> mono = webClient.get().uri(uri).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange().doOnSuccess(clientResponse -> log.info("----- headers: {}", clientResponse.headers())).doOnSuccess(clientResponse -> log.info("----- statusCode: {}", clientResponse.statusCode())).flatMap(clientResponse -> clientResponse.bodyToMono(String.class));mono.subscribe(body -> log.info("----- reponse: {}", body));TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testGet005()throws InterruptedException{Mono<String> mono = webClient.get().uri(uriBuilder -> uriBuilder.scheme("https").host("httpbin.org").path("/get").queryParam("q1", "java").queryParam("q2", "python").build()).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).retrieve().bodyToMono(String.class);mono.subscribe(body -> log.info("----- reponse: {}", body));TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testJsonBody001()throws InterruptedException{Mono<String> mono = webClient.post().uri(uriBuilder -> uriBuilder.scheme("https").host("httpbin.org").path("/post").build()).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).contentType(MediaType.APPLICATION_JSON).bodyValue(Collections.singletonMap("q", "java")).retrieve().bodyToMono(String.class);mono.subscribe(body -> log.info("----- reponse: {}", body));TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用* * @throws IOException* @throws InterruptedException*/@Testpublic void testJsonBody002()throws IOException, InterruptedException{Mono<String> mono;int num = RandomUtils.nextInt(1, 4);switch (num){case 1: // 方式1,javaBeanSearchReq req = new SearchReq();req.setPageNo(1);req.setPageSize(10);req.setKeyword("1");mono = webClient.post().uri("https://httpbin.org/post").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).bodyValue(req) // 设置JsonBody.retrieve().bodyToMono(String.class);mono.subscribe(body -> log.info("reponse: {}", body));break;case 2: // 方式2,HashMapMap<String, String> params = new HashMap<>();params.put("pageNo", "2");params.put("pageSize", "20");params.put("keyword", "2");mono = webClient.post().uri("https://httpbin.org/post").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).bodyValue(params) // 设置JsonBody.retrieve().bodyToMono(String.class);mono.subscribe(body -> log.info("reponse: {}", body));break;case 3: // 方式3,json字符串Map<String, String> params2 = new HashMap<>();params2.put("pageNo", "2");params2.put("pageSize", "20");params2.put("keyword", "2");mono = webClient.post().uri("https://httpbin.org/post").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromValue(JsonBeanUtils.beanToJson(params2, false))) // 设置formData.retrieve().bodyToMono(String.class);mono.subscribe(body -> log.info("reponse: {}", body));break;}TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testUpload001()throws InterruptedException{MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();params.add("q1", "java");params.add("q2", "python");params.add("file", new ClassPathResource("123.jpg"));Mono<String> mono = webClient.post().uri("https://httpbin.org/post").contentType(MediaType.APPLICATION_FORM_URLENCODED).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromMultipartData(params)) // 设置formData,等价 BodyInserters.fromFormData("q1", "java").with("q2", "python").retrieve() // 获取响应体.bodyToMono(String.class); // 响应数据类型转换mono.subscribe(body -> log.info("----- reponse: {}", body));TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testUpload002()throws InterruptedException{Mono<String> mono = webClient.post().uri("https://httpbin.org/post").contentType(MediaType.APPLICATION_FORM_URLENCODED).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromMultipartData("q1", "java").with("q2", "python").with("file", new ClassPathResource("123.jpg"))).retrieve() // 获取响应体.bodyToMono(String.class); // 响应数据类型转换mono.subscribe(body -> log.info("----- reponse: {}", body));TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}
}

2、同步代码


import java.awt.Desktop;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;import javax.imageio.ImageIO;import org.apache.commons.lang3.RandomUtils;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;import com.fly.http.bean.ImageShowDialog;
import com.fly.http.bean.JsonBeanUtils;
import com.fly.http.bean.SearchReq;import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;/*** http请求WebClient同步调用实现*/
@Slf4j
public class WebClientSyncTest
{private WebClient webClient = WebClient.builder().codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(-1)).build();private void openImage(Resource resource){try{new ImageShowDialog(ImageIO.read(resource.getInputStream()));}catch (IOException e){log.error(e.getMessage(), e);}}@BeforeClasspublic static void init(){new File("download").mkdirs();}/*** WebClient同步调用* * @throws IOException*/@Testpublic void testDownFile()throws IOException{Mono<ClientResponse> mono = webClient.get().uri("https://00fly.online/upload/urls.txt").accept(MediaType.IMAGE_JPEG).exchange();ClientResponse response = mono.block();log.info("----- headers: {}", response.headers());log.info("----- statusCode: {}", response.statusCode());// 保存到本地Resource resource = response.bodyToMono(Resource.class).block();FileCopyUtils.copy(resource.getInputStream(), new FileOutputStream("download/urls.txt"));}/*** WebClient同步调用* * @throws IOException* @throws InterruptedException*/@Testpublic void testDownImg001()throws IOException, InterruptedException{Mono<Resource> mono = webClient.get().uri("https://00fly.online/upload/2019/02/201902262129360274AKuFZcUfip.jpg").accept(MediaType.IMAGE_JPEG).retrieve() // 获取响应体.bodyToMono(Resource.class);openImage(mono.block());TimeUnit.SECONDS.sleep(10);}/*** WebClient同步调用* * @throws IOException*/@Testpublic void testDownImg002()throws IOException{Mono<Resource> mono = webClient.get().uri("https://00fly.online/upload/2019/02/201902262129360274AKuFZcUfip.jpg").accept(MediaType.IMAGE_JPEG).retrieve() // 获取响应体.bodyToMono(Resource.class);// 保存到本地Resource resource = mono.block();File dest = new File(String.format("download/img_%s.jpg", System.currentTimeMillis()));FileCopyUtils.copy(resource.getInputStream(), new FileOutputStream(dest));if (Desktop.isDesktopSupported()){Desktop.getDesktop().open(dest.getParentFile());}}/*** WebClient同步调用*/@Testpublic void testExchange001(){// getMultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("q1", "java");params.add("q2", "python");Mono<ClientResponse> monoGet = webClient.get().uri(uriBuilder -> uriBuilder.scheme("https").host("httpbin.org").path("/get").queryParams(params) // 等价 queryParam("q1", "java").queryParam("q2", "python").build()).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange();ClientResponse clientResponse = monoGet.block(); // 获取完整的响应对象log.info("----- headers: {}", clientResponse.headers());log.info("----- statusCode: {}", clientResponse.statusCode());log.info("----- reponse: {}", clientResponse.bodyToMono(String.class).block());}/*** WebClient同步调用*/@Testpublic void testExchange002(){// getMono<ClientResponse> monoGet = webClient.get().uri(uriBuilder -> uriBuilder.scheme("https").host("httpbin.org").path("/get").queryParam("q1", "java").queryParam("q2", "python").build()).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange();ClientResponse clientResponse = monoGet.block(); // 获取完整的响应对象log.info("----- headers: {}", clientResponse.headers());log.info("----- statusCode: {}", clientResponse.statusCode());log.info("----- reponse: {}", clientResponse.bodyToMono(String.class).block());// formData postMultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("q1", "java");params.add("q2", "python");Mono<ClientResponse> monoPost = webClient.post().uri("https://httpbin.org/post").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromFormData(params)) // 设置formData,等价 BodyInserters.fromFormData("q1", "java").with("q2", "python").exchange();ClientResponse clientResponse2 = monoPost.block(); // 获取完整的响应对象log.info("----- headers: {}", clientResponse2.headers());log.info("----- statusCode: {}", clientResponse2.statusCode());log.info("----- reponse: {}", clientResponse2.bodyToMono(String.class).block());}/*** WebClient同步调用*/@Testpublic void testFormDataPost(){MultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("q1", "java");params.add("q2", "python");Mono<String> mono = webClient.post().uri("https://httpbin.org/post").contentType(MediaType.APPLICATION_FORM_URLENCODED).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromFormData(params)) // 设置formData,等价 BodyInserters.fromFormData("q1", "java").with("q2", "python").retrieve() // 获取响应体.bodyToMono(String.class); // 响应数据类型转换log.info("reponse: {}", mono.block());}/*** WebClient同步调用*/@Testpublic void testGet001(){Mono<String> mono = webClient.get().uri("https://httpbin.org/{method}", "get") // {任意命名}.acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).retrieve().bodyToMono(String.class);log.info("reponse: {}", mono.block());}/*** WebClient同步调用*/@Testpublic void testGet002(){Mono<String> mono = webClient.get().uri("https://httpbin.org/get").acceptCharset(StandardCharsets.UTF_8).exchange().doOnSuccess(clientResponse -> log.info("----- headers: {}", clientResponse.headers())).doOnSuccess(clientResponse -> log.info("----- statusCode: {}", clientResponse.statusCode())).flatMap(clientResponse -> clientResponse.bodyToMono(String.class));log.info("reponse: {}", mono.block());}/*** WebClient同步调用* */@Testpublic void testGet003(){Mono<String> mono = webClient.get().uri("https://httpbin.org/get").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange().doOnSuccess(clientResponse -> log.info("----- headers: {}", clientResponse.headers())).doOnSuccess(clientResponse -> log.info("----- statusCode: {}", clientResponse.statusCode())).flatMap(clientResponse -> clientResponse.bodyToMono(String.class));log.info("reponse: {}", mono.block());}/*** WebClient同步调用, https://httpbin.org/get?q=java* */@Testpublic void testGet004(){MultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("q", "java");String uri = UriComponentsBuilder.fromUriString("https://httpbin.org/get").queryParams(params).toUriString();// 注意比较// uri = UriComponentsBuilder.fromUriString("https://httpbin.org/get").queryParam("q", "java", "python").toUriString();// uri = UriComponentsBuilder.fromUriString("https://httpbin.org/get").queryParam("q1", "java").queryParam("q2", "python").toUriString();Mono<String> mono = webClient.get().uri(uri).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange().doOnSuccess(clientResponse -> log.info("----- headers: {}", clientResponse.headers())).doOnSuccess(clientResponse -> log.info("----- statusCode: {}", clientResponse.statusCode())).flatMap(clientResponse -> clientResponse.bodyToMono(String.class));log.info("reponse: {}", mono.block());}/*** WebClient同步调用* */@Testpublic void testGet005(){Mono<String> mono = webClient.get().uri(uriBuilder -> uriBuilder.scheme("https").host("httpbin.org").path("/get").queryParam("q1", "java").queryParam("q2", "python").build()).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).retrieve().bodyToMono(String.class);log.info("reponse: {}", mono.block());}/*** WebClient同步调用* */@Testpublic void testJsonBody001(){Mono<String> mono = webClient.post().uri(uriBuilder -> uriBuilder.scheme("https").host("httpbin.org").path("/post").build()).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).contentType(MediaType.APPLICATION_JSON).bodyValue(Collections.singletonMap("q", "java")).retrieve().bodyToMono(String.class);log.info("reponse: {}", mono.block());}/*** WebClient同步调用* * @throws IOException*/@Testpublic void testJsonBody002()throws IOException{Mono<String> mono;int num = RandomUtils.nextInt(1, 4);switch (num){case 1: // 方式1,javaBeanSearchReq req = new SearchReq();req.setPageNo(1);req.setPageSize(10);req.setKeyword("1");mono = webClient.post().uri("https://httpbin.org/post").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).bodyValue(req) // 设置JsonBody.retrieve().bodyToMono(String.class);log.info("reponse: {}", mono.block());break;case 2: // 方式2,HashMapMap<String, String> params = new HashMap<>();params.put("pageNo", "2");params.put("pageSize", "20");params.put("keyword", "2");mono = webClient.post().uri("https://httpbin.org/post").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).bodyValue(params) // 设置JsonBody.retrieve().bodyToMono(String.class);log.info("reponse: {}", mono.block());break;case 3: // 方式3,json字符串Map<String, String> params2 = new HashMap<>();params2.put("pageNo", "2");params2.put("pageSize", "20");params2.put("keyword", "2");mono = webClient.post().uri("https://httpbin.org/post").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromValue(JsonBeanUtils.beanToJson(params2, false))) // 设置formData.retrieve().bodyToMono(String.class);log.info("reponse: {}", mono.block());break;}}/*** WebClient同步调用* */@Testpublic void testUpload001(){MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();params.add("q1", "java");params.add("q2", "python");params.add("file", new ClassPathResource("123.jpg"));Mono<String> mono = webClient.post().uri("https://httpbin.org/post").contentType(MediaType.APPLICATION_FORM_URLENCODED).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromMultipartData(params)) // 设置formData,等价 BodyInserters.fromFormData("q1", "java").with("q2", "python").retrieve() // 获取响应体.bodyToMono(String.class); // 响应数据类型转换log.info("----- reponse: {}", mono.block());}/*** WebClient同步调用* */@Testpublic void testUpload002(){Mono<String> mono = webClient.post().uri("https://httpbin.org/post").contentType(MediaType.APPLICATION_FORM_URLENCODED).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromMultipartData("q1", "java").with("q2", "python").with("file", new ClassPathResource("123.jpg"))).retrieve() // 获取响应体.bodyToMono(String.class); // 响应数据类型转换log.info("----- reponse: {}", mono.block());}
}

3、完整代码

如何使用下面的备份文件恢复成原始的项目代码,请移步查阅:神奇代码恢复工具

//goto docker\docker-compose.yml
version: '3.7'
services:hello:image: registry.cn-shanghai.aliyuncs.com/00fly/web-client:0.0.1container_name: web-clientdeploy:resources:limits:cpus: '1'memory: 200Mreservations:cpus: '0.05'memory: 100Menvironment:JAVA_OPTS: -server -Xms100m -Xmx100m -Djava.security.egd=file:/dev/./urandomrestart: on-failurelogging:driver: json-fileoptions:max-size: 5mmax-file: '1'//goto docker\restart.sh
#!/bin/bash
docker-compose down && docker system prune -f && docker-compose up -d && docker stats
//goto docker\stop.sh
#!/bin/bash
docker-compose down
//goto Dockerfile
FROM openjdk:8-jre-alpineRUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezoneCOPY target/web-client-*.jar  /app.jarENTRYPOINT ["java","-jar","/app.jar"]
//goto pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.fly</groupId><artifactId>web-client</artifactId><version>0.0.1</version><name>web-client</name><packaging>jar</packaging><properties><docker.hub>registry.cn-shanghai.aliyuncs.com</docker.hub><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>1.8</java.version><skipTests>true</skipTests></properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-webflux</artifactId><version>5.2.3.RELEASE</version></dependency><dependency><groupId>io.projectreactor.netty</groupId><artifactId>reactor-netty</artifactId><version>0.9.4.RELEASE</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j-impl</artifactId><version>2.12.1</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.13.0</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.10</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.5</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version><scope>provided</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies><build><finalName>${project.artifactId}-${project.version}</finalName><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.10.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.4.0</version><configuration><createDependencyReducedPom>false</createDependencyReducedPom></configuration><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><minimizeJar>false</minimizeJar><filters><filter><artifact>*:*</artifact></filter></filters><transformers><!--MANIFEST文件中写入Main-Class是可执行包的必要条件。ManifestResourceTransformer可以轻松实现。 --><transformerimplementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>com.fly.http.RunMain</mainClass></transformer></transformers></configuration></execution></executions></plugin><!-- 添加docker-maven插件 --><plugin><groupId>io.fabric8</groupId><artifactId>docker-maven-plugin</artifactId><version>0.40.0</version><executions><execution><phase>package</phase><goals><goal>build</goal><goal>push</goal><goal>remove</goal></goals></execution></executions><configuration><!-- 连接到带docker环境的linux服务器编译image --><!-- <dockerHost>http://192.168.182.10:2375</dockerHost> --><!-- Docker 推送镜像仓库地址 --><pushRegistry>${docker.hub}</pushRegistry><images><image><name>${docker.hub}/00fly/${project.artifactId}:${project.version}</name><build><dockerFileDir>${project.basedir}</dockerFileDir></build></image></images></configuration></plugin></plugins></build>
</project>
//goto src\main\java\com\fly\http\FluxWebClient.java
package com.fly.http;import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;import lombok.extern.slf4j.Slf4j;/*** WebClient是RestTemplete的替代品,有更好的响应式能力,支持异步调用<br>* * https://blog.csdn.net/zzhongcy/article/details/105412842* */
@Slf4j
public class FluxWebClient
{private List<String> urls = new ArrayList<>();// 缓冲区默认256k,设为-1以解决报错Exceeded limit on max bytes to buffer : 262144private WebClient webClient = WebClient.builder().codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(-1)).build();public void visitAll(){// block转换为同步调用if (urls.isEmpty()){log.info("★★★★★★★★ urls isEmpty, now get urls from api ★★★★★★★★");String resp = webClient.get().uri("https://00fly.online/upload/urls.txt").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.TEXT_HTML).retrieve().bodyToMono(String.class).block();urls = Arrays.asList(StringUtils.split(resp, "\r\n"));}// 异步访问AtomicInteger count = new AtomicInteger(0);urls.stream().filter(url -> RandomUtils.nextBoolean()).forEach(url -> webClient.get().uri(url).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.TEXT_HTML).retrieve().bodyToMono(String.class).subscribe(r -> log.info("process complted: {}. {}", count.incrementAndGet(), url), e -> log.error(e.getMessage())));log.info("total:{} ==> ############## 异步请求已提交 ##############", urls.size());}
}
//goto src\main\java\com\fly\http\RunMain.java
package com.fly.http;import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;import lombok.extern.slf4j.Slf4j;@Slf4j
public class RunMain
{private static FluxWebClient webClient = new FluxWebClient();/*** 程序运行入口* */public static void main(String[] args){scheduledThreadPoolExecutorStart();}private static void scheduledThreadPoolExecutorStart(){new ScheduledThreadPoolExecutor(2).scheduleAtFixedRate(() -> {webClient.visitAll();}, 0L, 30, TimeUnit.SECONDS);log.info("======== ScheduledThreadPoolExecutor started!");}/*** Timer线程安全, 但单线程执行, 抛出异常时, task会终止*/@Deprecatedprotected static void timeStart(){new Timer().scheduleAtFixedRate(new TimerTask(){@Overridepublic void run(){webClient.visitAll();}}, 0L, 30 * 1000L);log.info("======== Timer started!");}
}
//goto src\main\resources\log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="off" monitorInterval="0"><appenders><console name="Console" target="system_out"><patternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p %pid --- [%t] %-30.30c{1.} : %m%n" /></console></appenders><loggers><root level="INFO"><appender-ref ref="Console" /></root></loggers>
</configuration>
//goto src\test\java\com\fly\http\ApiTest.java
package com.fly.http;import java.awt.Desktop;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.util.ResourceUtils;
import org.springframework.web.reactive.function.client.WebClient;import lombok.extern.slf4j.Slf4j;@Slf4j
public class ApiTest
{// 缓冲区默认256k,设为-1以解决报错Exceeded limit on max bytes to buffer : 262144private WebClient webClient = WebClient.builder().codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(-1)).build();/*** 写入文本文件* * @param urls* @see [类、类#方法、类#成员]*/private void process(List<String> urls){try{if (ResourceUtils.isFileURL(ResourceUtils.getURL(ResourceUtils.CLASSPATH_URL_PREFIX))){String path = ResourceUtils.getURL(ResourceUtils.CLASSPATH_URL_PREFIX).getPath() + "urls.txt";File dest = new File(path);FileUtils.writeLines(dest, StandardCharsets.UTF_8.name(), urls);Desktop.getDesktop().open(dest);}}catch (IOException e){log.error(e.getMessage(), e);}}@Testpublic void test001()throws IOException{String jsonBody = webClient.get().uri("https://00fly.online/upload/data.json").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON).retrieve().bodyToMono(String.class).block().replace("{", "{\n").replace("}", "}\n").replace(",", ",\n");try (InputStream is = new ByteArrayInputStream(jsonBody.getBytes(StandardCharsets.UTF_8))){List<String> urls = IOUtils.readLines(is, StandardCharsets.UTF_8).stream().filter(line -> StringUtils.contains(line, "\"url\":")).map(n -> StringUtils.substringBetween(n, ":\"", "\",")).collect(Collectors.toList());log.info("★★★★★★★★ urls: {} ★★★★★★★★", urls.size());process(urls);}}@Testpublic void test002()throws IOException{Resource resource = new ClassPathResource("data.json");String jsonBody = IOUtils.toString(resource.getInputStream(), StandardCharsets.UTF_8).replace("{", "{\n").replace("}", "}\n").replace(",", ",\n");try (InputStream is = new ByteArrayInputStream(jsonBody.getBytes(StandardCharsets.UTF_8))){List<String> urls = IOUtils.readLines(is, StandardCharsets.UTF_8).stream().filter(line -> StringUtils.contains(line, "\"url\":")).map(n -> StringUtils.substringBetween(n, ":\"", "\",")).collect(Collectors.toList());log.info("★★★★★★★★ urls: {} ★★★★★★★★", urls.size());process(urls);}}@Testpublic void test003(){String resp = webClient.get().uri("https://00fly.online/upload/urls.txt").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.TEXT_HTML).retrieve().bodyToMono(String.class).block();List<String> urls = Arrays.asList(StringUtils.split(resp, "\r\n"));AtomicInteger count = new AtomicInteger(0);urls.stream().forEach(url -> log.info("{}. {}", count.incrementAndGet(), url));}
}
//goto src\test\java\com\fly\http\bean\ImageShowDialog.java
package com.fly.http.bean;import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.IOException;import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JLabel;import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;/*** * 弹出窗口* * @author 00fly* @version [版本号, 2023年3月3日]* @see [相关类/方法]* @since [产品/模块版本]*/
public class ImageShowDialog extends JDialog
{private static final long serialVersionUID = -7240357454480002551L;public static void main(String[] args)throws IOException{Resource resources = new ClassPathResource("123.jpg");BufferedImage image = ImageIO.read(resources.getInputStream());new ImageShowDialog(image);}public ImageShowDialog(BufferedImage image){super();setTitle("图片查看工具");setSize(image.getWidth(), image.getHeight() + 30);Dimension screenSize = getToolkit().getScreenSize();Dimension dialogSize = getSize();dialogSize.height = Math.min(screenSize.height, dialogSize.height);dialogSize.width = Math.min(screenSize.width, dialogSize.width);setLocation((screenSize.width - dialogSize.width) / 2, (screenSize.height - dialogSize.height) / 2);add(new JLabel(new ImageIcon(image)));setVisible(true);setResizable(false);setAlwaysOnTop(true);setDefaultCloseOperation(DISPOSE_ON_CLOSE);}
}
//goto src\test\java\com\fly\http\bean\JsonBeanUtils.java
package com.fly.http.bean;import java.io.IOException;import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;/*** JsonBean转换工具* * @author 00fly**/
public class JsonBeanUtils
{private static ObjectMapper objectMapper = new ObjectMapper();/*** bean转json字符串* * @param bean* @return* @throws IOException*/public static String beanToJson(Object bean)throws IOException{String jsonText = objectMapper.writeValueAsString(bean);return objectMapper.readTree(jsonText).toPrettyString();}/*** bean转json字符串* * @param bean* @param pretty 是否格式美化* @return* @throws IOException*/public static String beanToJson(Object bean, boolean pretty)throws IOException{String jsonText = objectMapper.writeValueAsString(bean);if (pretty){return objectMapper.readTree(jsonText).toPrettyString();}return objectMapper.readTree(jsonText).toString();}/*** json字符串转bean* * @param jsonText* @return* @throws IOException*/public static <T> T jsonToBean(String jsonText, Class<T> clazz)throws IOException{return objectMapper.readValue(jsonText, clazz);}/*** json字符串转bean* * @param jsonText* @return* @throws IOException*/public static <T> T jsonToBean(String jsonText, JavaType javaType)throws IOException{return objectMapper.readValue(jsonText, javaType);}/*** json字符串转bean* * @param jsonText* @return* @throws IOException*/public static <T> T jsonToBean(String jsonText, TypeReference<T> typeRef)throws IOException{return objectMapper.readValue(jsonText, typeRef);}
}
//goto src\test\java\com\fly\http\bean\SearchReq.java
package com.fly.http.bean;import lombok.Data;@Data
public class SearchReq
{Integer pageNo = 1;Integer pageSize = 10;String keyword;
}
//goto src\test\java\com\fly\http\WebClientAsyncTest.java
package com.fly.http;import java.awt.Desktop;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;import javax.imageio.ImageIO;import org.apache.commons.lang3.RandomUtils;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;import com.fly.http.bean.ImageShowDialog;
import com.fly.http.bean.JsonBeanUtils;
import com.fly.http.bean.SearchReq;import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;/*** http请求WebClient异步调用实现*/
@Slf4j
public class WebClientAsyncTest
{private WebClient webClient = WebClient.builder().codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(-1)).build();private void openImage(Resource resource){try{new ImageShowDialog(ImageIO.read(resource.getInputStream()));}catch (IOException e){log.error(e.getMessage(), e);}}@BeforeClasspublic static void init(){new File("download").mkdirs();}/*** WebClient异步调用* * @throws IOException* @throws InterruptedException*/@Testpublic void testDownFile()throws IOException, InterruptedException{Mono<Resource> mono = webClient.get().uri("https://00fly.online/upload/urls.txt").accept(MediaType.IMAGE_JPEG).exchange().doOnSuccess(clientResponse -> log.info("----- headers: {}", clientResponse.headers())).doOnSuccess(clientResponse -> log.info("----- statusCode: {}", clientResponse.statusCode())).flatMap(clientResponse -> clientResponse.bodyToMono(Resource.class));// 保存到本地mono.subscribe(resource -> {try{FileCopyUtils.copy(resource.getInputStream(), new FileOutputStream("download/urls.txt"));}catch (IOException e){log.error(e.getMessage(), e);}});TimeUnit.SECONDS.sleep(2);}/*** WebClient异步调用* * @throws IOException* @throws InterruptedException*/@Testpublic void testDownImg001()throws IOException, InterruptedException{Mono<Resource> mono = webClient.get().uri("https://00fly.online/upload/2019/02/201902262129360274AKuFZcUfip.jpg").accept(MediaType.IMAGE_JPEG).retrieve() // 获取响应体.bodyToMono(Resource.class);mono.subscribe(resource -> openImage(resource));TimeUnit.SECONDS.sleep(10);}/*** WebClient异步调用* * @throws IOException* @throws InterruptedException*/@Testpublic void testDownImg002()throws IOException, InterruptedException{Mono<Resource> mono = webClient.get().uri("https://00fly.online/upload/2019/02/201902262129360274AKuFZcUfip.jpg").accept(MediaType.IMAGE_JPEG).retrieve() // 获取响应体.bodyToMono(Resource.class);// 保存到本地mono.subscribe(resource -> {try{File dest = new File(String.format("download/img_%s.jpg", System.currentTimeMillis()));FileCopyUtils.copy(resource.getInputStream(), new FileOutputStream(dest));if (Desktop.isDesktopSupported()){Desktop.getDesktop().open(dest.getParentFile());}}catch (IOException e){log.error(e.getMessage(), e);}});TimeUnit.SECONDS.sleep(2);}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testExchange001()throws InterruptedException{// getMultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("q1", "java");params.add("q2", "python");Mono<ClientResponse> monoGet = webClient.get().uri(uriBuilder -> uriBuilder.scheme("https").host("httpbin.org").path("/get").queryParams(params) // 等价 queryParam("q1", "java").queryParam("q2", "python").build()).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange();monoGet.subscribe(clientResponse -> {log.info("----- headers: {}", clientResponse.headers());log.info("----- statusCode: {}", clientResponse.statusCode());clientResponse.bodyToMono(String.class).subscribe(body -> log.info("----- reponse: {}", body));});TimeUnit.SECONDS.sleep(2);}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testExchange002()throws InterruptedException{// getMono<ClientResponse> monoGet = webClient.get().uri(uriBuilder -> uriBuilder.scheme("https").host("httpbin.org").path("/get").queryParam("q1", "java").queryParam("q2", "python").build()).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange();monoGet.subscribe(clientResponse -> {log.info("----- headers: {}", clientResponse.headers());log.info("----- statusCode: {}", clientResponse.statusCode());clientResponse.bodyToMono(String.class).subscribe(body -> log.info("----- reponse: {}", body));});// formData postMultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("q1", "java");params.add("q2", "python");Mono<ClientResponse> monoPost = webClient.post().uri("https://httpbin.org/post").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromFormData(params)) // 设置formData,等价 BodyInserters.fromFormData("q1", "java").with("q2", "python").exchange();monoPost.subscribe(clientResponse -> {log.info("----- headers: {}", clientResponse.headers());log.info("----- statusCode: {}", clientResponse.statusCode());clientResponse.bodyToMono(String.class).subscribe(body -> log.info("----- reponse: {}", body));});TimeUnit.SECONDS.sleep(2);}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testFormDataPost()throws InterruptedException{MultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("q1", "java");params.add("q2", "python");Mono<String> mono = webClient.post().uri("https://httpbin.org/post").contentType(MediaType.APPLICATION_FORM_URLENCODED).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromFormData(params)) // 设置formData,等价 BodyInserters.fromFormData("q1", "java").with("q2", "python").retrieve() // 获取响应体.bodyToMono(String.class); // 响应数据类型转换mono.subscribe(body -> log.info("----- reponse: {}", body));TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testGet001()throws InterruptedException{Mono<String> mono = webClient.get().uri("https://httpbin.org/{method}", "get") // {任意命名}.acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).retrieve().bodyToMono(String.class);mono.subscribe(body -> log.info("----- reponse: {}", body));TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testGet002()throws InterruptedException{Mono<ClientResponse> mono = webClient.get().uri("https://httpbin.org/get").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange();mono.subscribe(reponse -> {log.info("----- headers: {}", reponse.headers());log.info("----- statusCode: {}", reponse.statusCode());reponse.bodyToMono(String.class).subscribe(body -> log.info("----- reponse: {}", body));});TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testGet003()throws InterruptedException{Mono<String> mono = webClient.get().uri("https://httpbin.org/get").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange().doOnSuccess(clientResponse -> log.info("----- headers: {}", clientResponse.headers())).doOnSuccess(clientResponse -> log.info("----- statusCode: {}", clientResponse.statusCode())).flatMap(clientResponse -> clientResponse.bodyToMono(String.class));mono.subscribe(body -> log.info("----- reponse: {}", body));TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用, https://httpbin.org/get?q=java* * @throws InterruptedException*/@Testpublic void testGet004()throws InterruptedException{MultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("q", "java");String uri = UriComponentsBuilder.fromUriString("https://httpbin.org/get").queryParams(params).toUriString();// 注意比较// uri = UriComponentsBuilder.fromUriString("https://httpbin.org/get").queryParam("q", "java", "python").toUriString();// uri = UriComponentsBuilder.fromUriString("https://httpbin.org/get").queryParam("q1", "java").queryParam("q2", "python").toUriString();Mono<String> mono = webClient.get().uri(uri).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange().doOnSuccess(clientResponse -> log.info("----- headers: {}", clientResponse.headers())).doOnSuccess(clientResponse -> log.info("----- statusCode: {}", clientResponse.statusCode())).flatMap(clientResponse -> clientResponse.bodyToMono(String.class));mono.subscribe(body -> log.info("----- reponse: {}", body));TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testGet005()throws InterruptedException{Mono<String> mono = webClient.get().uri(uriBuilder -> uriBuilder.scheme("https").host("httpbin.org").path("/get").queryParam("q1", "java").queryParam("q2", "python").build()).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).retrieve().bodyToMono(String.class);mono.subscribe(body -> log.info("----- reponse: {}", body));TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testJsonBody001()throws InterruptedException{Mono<String> mono = webClient.post().uri(uriBuilder -> uriBuilder.scheme("https").host("httpbin.org").path("/post").build()).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).contentType(MediaType.APPLICATION_JSON).bodyValue(Collections.singletonMap("q", "java")).retrieve().bodyToMono(String.class);mono.subscribe(body -> log.info("----- reponse: {}", body));TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用* * @throws IOException* @throws InterruptedException*/@Testpublic void testJsonBody002()throws IOException, InterruptedException{Mono<String> mono;int num = RandomUtils.nextInt(1, 4);switch (num){case 1: // 方式1,javaBeanSearchReq req = new SearchReq();req.setPageNo(1);req.setPageSize(10);req.setKeyword("1");mono = webClient.post().uri("https://httpbin.org/post").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).bodyValue(req) // 设置JsonBody.retrieve().bodyToMono(String.class);mono.subscribe(body -> log.info("reponse: {}", body));break;case 2: // 方式2,HashMapMap<String, String> params = new HashMap<>();params.put("pageNo", "2");params.put("pageSize", "20");params.put("keyword", "2");mono = webClient.post().uri("https://httpbin.org/post").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).bodyValue(params) // 设置JsonBody.retrieve().bodyToMono(String.class);mono.subscribe(body -> log.info("reponse: {}", body));break;case 3: // 方式3,json字符串Map<String, String> params2 = new HashMap<>();params2.put("pageNo", "2");params2.put("pageSize", "20");params2.put("keyword", "2");mono = webClient.post().uri("https://httpbin.org/post").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromValue(JsonBeanUtils.beanToJson(params2, false))) // 设置formData.retrieve().bodyToMono(String.class);mono.subscribe(body -> log.info("reponse: {}", body));break;}TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testUpload001()throws InterruptedException{MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();params.add("q1", "java");params.add("q2", "python");params.add("file", new ClassPathResource("123.jpg"));Mono<String> mono = webClient.post().uri("https://httpbin.org/post").contentType(MediaType.APPLICATION_FORM_URLENCODED).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromMultipartData(params)) // 设置formData,等价 BodyInserters.fromFormData("q1", "java").with("q2", "python").retrieve() // 获取响应体.bodyToMono(String.class); // 响应数据类型转换mono.subscribe(body -> log.info("----- reponse: {}", body));TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}/*** WebClient异步调用* * @throws InterruptedException*/@Testpublic void testUpload002()throws InterruptedException{Mono<String> mono = webClient.post().uri("https://httpbin.org/post").contentType(MediaType.APPLICATION_FORM_URLENCODED).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromMultipartData("q1", "java").with("q2", "python").with("file", new ClassPathResource("123.jpg"))).retrieve() // 获取响应体.bodyToMono(String.class); // 响应数据类型转换mono.subscribe(body -> log.info("----- reponse: {}", body));TimeUnit.SECONDS.sleep(2); // 重要,等待异步调用完成}
}
//goto src\test\java\com\fly\http\WebClientSyncTest.java
package com.fly.http;import java.awt.Desktop;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;import javax.imageio.ImageIO;import org.apache.commons.lang3.RandomUtils;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;import com.fly.http.bean.ImageShowDialog;
import com.fly.http.bean.JsonBeanUtils;
import com.fly.http.bean.SearchReq;import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;/*** http请求WebClient同步调用实现*/
@Slf4j
public class WebClientSyncTest
{private WebClient webClient = WebClient.builder().codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(-1)).build();private void openImage(Resource resource){try{new ImageShowDialog(ImageIO.read(resource.getInputStream()));}catch (IOException e){log.error(e.getMessage(), e);}}@BeforeClasspublic static void init(){new File("download").mkdirs();}/*** WebClient同步调用* * @throws IOException*/@Testpublic void testDownFile()throws IOException{Mono<ClientResponse> mono = webClient.get().uri("https://00fly.online/upload/urls.txt").accept(MediaType.IMAGE_JPEG).exchange();ClientResponse response = mono.block();log.info("----- headers: {}", response.headers());log.info("----- statusCode: {}", response.statusCode());// 保存到本地Resource resource = response.bodyToMono(Resource.class).block();FileCopyUtils.copy(resource.getInputStream(), new FileOutputStream("download/urls.txt"));}/*** WebClient同步调用* * @throws IOException* @throws InterruptedException*/@Testpublic void testDownImg001()throws IOException, InterruptedException{Mono<Resource> mono = webClient.get().uri("https://00fly.online/upload/2019/02/201902262129360274AKuFZcUfip.jpg").accept(MediaType.IMAGE_JPEG).retrieve() // 获取响应体.bodyToMono(Resource.class);openImage(mono.block());TimeUnit.SECONDS.sleep(10);}/*** WebClient同步调用* * @throws IOException*/@Testpublic void testDownImg002()throws IOException{Mono<Resource> mono = webClient.get().uri("https://00fly.online/upload/2019/02/201902262129360274AKuFZcUfip.jpg").accept(MediaType.IMAGE_JPEG).retrieve() // 获取响应体.bodyToMono(Resource.class);// 保存到本地Resource resource = mono.block();File dest = new File(String.format("download/img_%s.jpg", System.currentTimeMillis()));FileCopyUtils.copy(resource.getInputStream(), new FileOutputStream(dest));if (Desktop.isDesktopSupported()){Desktop.getDesktop().open(dest.getParentFile());}}/*** WebClient同步调用*/@Testpublic void testExchange001(){// getMultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("q1", "java");params.add("q2", "python");Mono<ClientResponse> monoGet = webClient.get().uri(uriBuilder -> uriBuilder.scheme("https").host("httpbin.org").path("/get").queryParams(params) // 等价 queryParam("q1", "java").queryParam("q2", "python").build()).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange();ClientResponse clientResponse = monoGet.block(); // 获取完整的响应对象log.info("----- headers: {}", clientResponse.headers());log.info("----- statusCode: {}", clientResponse.statusCode());log.info("----- reponse: {}", clientResponse.bodyToMono(String.class).block());}/*** WebClient同步调用*/@Testpublic void testExchange002(){// getMono<ClientResponse> monoGet = webClient.get().uri(uriBuilder -> uriBuilder.scheme("https").host("httpbin.org").path("/get").queryParam("q1", "java").queryParam("q2", "python").build()).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange();ClientResponse clientResponse = monoGet.block(); // 获取完整的响应对象log.info("----- headers: {}", clientResponse.headers());log.info("----- statusCode: {}", clientResponse.statusCode());log.info("----- reponse: {}", clientResponse.bodyToMono(String.class).block());// formData postMultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("q1", "java");params.add("q2", "python");Mono<ClientResponse> monoPost = webClient.post().uri("https://httpbin.org/post").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromFormData(params)) // 设置formData,等价 BodyInserters.fromFormData("q1", "java").with("q2", "python").exchange();ClientResponse clientResponse2 = monoPost.block(); // 获取完整的响应对象log.info("----- headers: {}", clientResponse2.headers());log.info("----- statusCode: {}", clientResponse2.statusCode());log.info("----- reponse: {}", clientResponse2.bodyToMono(String.class).block());}/*** WebClient同步调用*/@Testpublic void testFormDataPost(){MultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("q1", "java");params.add("q2", "python");Mono<String> mono = webClient.post().uri("https://httpbin.org/post").contentType(MediaType.APPLICATION_FORM_URLENCODED).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromFormData(params)) // 设置formData,等价 BodyInserters.fromFormData("q1", "java").with("q2", "python").retrieve() // 获取响应体.bodyToMono(String.class); // 响应数据类型转换log.info("reponse: {}", mono.block());}/*** WebClient同步调用*/@Testpublic void testGet001(){Mono<String> mono = webClient.get().uri("https://httpbin.org/{method}", "get") // {任意命名}.acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).retrieve().bodyToMono(String.class);log.info("reponse: {}", mono.block());}/*** WebClient同步调用*/@Testpublic void testGet002(){Mono<String> mono = webClient.get().uri("https://httpbin.org/get").acceptCharset(StandardCharsets.UTF_8).exchange().doOnSuccess(clientResponse -> log.info("----- headers: {}", clientResponse.headers())).doOnSuccess(clientResponse -> log.info("----- statusCode: {}", clientResponse.statusCode())).flatMap(clientResponse -> clientResponse.bodyToMono(String.class));log.info("reponse: {}", mono.block());}/*** WebClient同步调用* */@Testpublic void testGet003(){Mono<String> mono = webClient.get().uri("https://httpbin.org/get").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange().doOnSuccess(clientResponse -> log.info("----- headers: {}", clientResponse.headers())).doOnSuccess(clientResponse -> log.info("----- statusCode: {}", clientResponse.statusCode())).flatMap(clientResponse -> clientResponse.bodyToMono(String.class));log.info("reponse: {}", mono.block());}/*** WebClient同步调用, https://httpbin.org/get?q=java* */@Testpublic void testGet004(){MultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("q", "java");String uri = UriComponentsBuilder.fromUriString("https://httpbin.org/get").queryParams(params).toUriString();// 注意比较// uri = UriComponentsBuilder.fromUriString("https://httpbin.org/get").queryParam("q", "java", "python").toUriString();// uri = UriComponentsBuilder.fromUriString("https://httpbin.org/get").queryParam("q1", "java").queryParam("q2", "python").toUriString();Mono<String> mono = webClient.get().uri(uri).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).exchange().doOnSuccess(clientResponse -> log.info("----- headers: {}", clientResponse.headers())).doOnSuccess(clientResponse -> log.info("----- statusCode: {}", clientResponse.statusCode())).flatMap(clientResponse -> clientResponse.bodyToMono(String.class));log.info("reponse: {}", mono.block());}/*** WebClient同步调用* */@Testpublic void testGet005(){Mono<String> mono = webClient.get().uri(uriBuilder -> uriBuilder.scheme("https").host("httpbin.org").path("/get").queryParam("q1", "java").queryParam("q2", "python").build()).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).retrieve().bodyToMono(String.class);log.info("reponse: {}", mono.block());}/*** WebClient同步调用* */@Testpublic void testJsonBody001(){Mono<String> mono = webClient.post().uri(uriBuilder -> uriBuilder.scheme("https").host("httpbin.org").path("/post").build()).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).contentType(MediaType.APPLICATION_JSON).bodyValue(Collections.singletonMap("q", "java")).retrieve().bodyToMono(String.class);log.info("reponse: {}", mono.block());}/*** WebClient同步调用* * @throws IOException*/@Testpublic void testJsonBody002()throws IOException{Mono<String> mono;int num = RandomUtils.nextInt(1, 4);switch (num){case 1: // 方式1,javaBeanSearchReq req = new SearchReq();req.setPageNo(1);req.setPageSize(10);req.setKeyword("1");mono = webClient.post().uri("https://httpbin.org/post").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).bodyValue(req) // 设置JsonBody.retrieve().bodyToMono(String.class);log.info("reponse: {}", mono.block());break;case 2: // 方式2,HashMapMap<String, String> params = new HashMap<>();params.put("pageNo", "2");params.put("pageSize", "20");params.put("keyword", "2");mono = webClient.post().uri("https://httpbin.org/post").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).bodyValue(params) // 设置JsonBody.retrieve().bodyToMono(String.class);log.info("reponse: {}", mono.block());break;case 3: // 方式3,json字符串Map<String, String> params2 = new HashMap<>();params2.put("pageNo", "2");params2.put("pageSize", "20");params2.put("keyword", "2");mono = webClient.post().uri("https://httpbin.org/post").acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromValue(JsonBeanUtils.beanToJson(params2, false))) // 设置formData.retrieve().bodyToMono(String.class);log.info("reponse: {}", mono.block());break;}}/*** WebClient同步调用* */@Testpublic void testUpload001(){MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();params.add("q1", "java");params.add("q2", "python");params.add("file", new ClassPathResource("123.jpg"));Mono<String> mono = webClient.post().uri("https://httpbin.org/post").contentType(MediaType.APPLICATION_FORM_URLENCODED).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromMultipartData(params)) // 设置formData,等价 BodyInserters.fromFormData("q1", "java").with("q2", "python").retrieve() // 获取响应体.bodyToMono(String.class); // 响应数据类型转换log.info("----- reponse: {}", mono.block());}/*** WebClient同步调用* */@Testpublic void testUpload002(){Mono<String> mono = webClient.post().uri("https://httpbin.org/post").contentType(MediaType.APPLICATION_FORM_URLENCODED).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML).body(BodyInserters.fromMultipartData("q1", "java").with("q2", "python").with("file", new ClassPathResource("123.jpg"))).retrieve() // 获取响应体.bodyToMono(String.class); // 响应数据类型转换log.info("----- reponse: {}", mono.block());}
}

有任何问题和建议,都可以向我提问讨论,大家一起进步,谢谢!

-over-

这篇关于WebClient 同步、异步调用实现对比的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/835674

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Python调用Orator ORM进行数据库操作

《Python调用OratorORM进行数据库操作》OratorORM是一个功能丰富且灵活的PythonORM库,旨在简化数据库操作,它支持多种数据库并提供了简洁且直观的API,下面我们就... 目录Orator ORM 主要特点安装使用示例总结Orator ORM 是一个功能丰富且灵活的 python O

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形