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

爱码少年 00fly.online 2024-07-28 16:03:02 阅读 60

文章目录

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

一、概述

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

二、pom依赖

<code><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、异步代码

<code>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);

}

}

@BeforeClass

public static void init()

{

new File("download").mkdirs();

}

/**

* WebClient异步调用

*

* @throws IOException

* @throws InterruptedException

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public void testExchange001()

throws InterruptedException

{

// get

MultiValueMap<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

*/

@Test

public void testExchange002()

throws InterruptedException

{

// get

Mono<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 post

MultiValueMap<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

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public void testJsonBody002()

throws IOException, InterruptedException

{

Mono<String> mono;

int num = RandomUtils.nextInt(1, 4);

switch (num)

{

case 1: // 方式1,javaBean

SearchReq 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,HashMap

Map<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

*/

@Test

public 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

*/

@Test

public 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);

}

}

@BeforeClass

public static void init()

{

new File("download").mkdirs();

}

/**

* WebClient同步调用

*

* @throws IOException

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public 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同步调用

*/

@Test

public void testExchange001()

{

// get

MultiValueMap<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同步调用

*/

@Test

public void testExchange002()

{

// get

Mono<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 post

MultiValueMap<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同步调用

*/

@Test

public 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同步调用

*/

@Test

public 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同步调用

*/

@Test

public 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同步调用

*

*/

@Test

public 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

*

*/

@Test

public 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同步调用

*

*/

@Test

public 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同步调用

*

*/

@Test

public 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

*/

@Test

public void testJsonBody002()

throws IOException

{

Mono<String> mono;

int num = RandomUtils.nextInt(1, 4);

switch (num)

{

case 1: // 方式1,javaBean

SearchReq 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,HashMap

Map<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同步调用

*

*/

@Test

public 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同步调用

*

*/

@Test

public 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.1

container_name: web-client

deploy:

resources:

limits:

cpus: '1'

memory: 200M

reservations:

cpus: '0.05'

memory: 100M

environment:

JAVA_OPTS: -server -Xms100m -Xmx100m -Djava.security.egd=file:/dev/./urandom

restart: on-failure

logging:

driver: json-file

options:

max-size: 5m

max-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-alpine

RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone

COPY target/web-client-*.jar /app.jar

ENTRYPOINT ["java","-jar","/app.jar"]

//goto pom.xml

<?xml version="1.0" encoding="UTF-8"?>code>

<project xmlns="http://maven.apache.org/POM/4.0.0"code>

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"code>

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">code>

<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可以轻松实现。 -->

<transformer

implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">code>

<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 : 262144

private 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会终止

*/

@Deprecated

protected static void timeStart()

{

new Timer().scheduleAtFixedRate(new TimerTask()

{

@Override

public void run()

{

webClient.visitAll();

}

}, 0L, 30 * 1000L);

log.info("======== Timer started!");

}

}

//goto src\main\resources\log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>code>

<configuration status="off" monitorInterval="0">code>

<appenders>

<console name="Console" target="system_out">code>

<patternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p %pid --- [%t] %-30.30c{1.} : %m%n" />code>

</console>

</appenders>

<loggers>

<root level="INFO">code>

<appender-ref ref="Console" />code>

</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 : 262144

private 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);

}

}

@Test

public 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);

}

}

@Test

public 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);

}

}

@Test

public 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);

}

}

@BeforeClass

public static void init()

{

new File("download").mkdirs();

}

/**

* WebClient异步调用

*

* @throws IOException

* @throws InterruptedException

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public void testExchange001()

throws InterruptedException

{

// get

MultiValueMap<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

*/

@Test

public void testExchange002()

throws InterruptedException

{

// get

Mono<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 post

MultiValueMap<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

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public void testJsonBody002()

throws IOException, InterruptedException

{

Mono<String> mono;

int num = RandomUtils.nextInt(1, 4);

switch (num)

{

case 1: // 方式1,javaBean

SearchReq 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,HashMap

Map<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

*/

@Test

public 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

*/

@Test

public 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);

}

}

@BeforeClass

public static void init()

{

new File("download").mkdirs();

}

/**

* WebClient同步调用

*

* @throws IOException

*/

@Test

public 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

*/

@Test

public 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

*/

@Test

public 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同步调用

*/

@Test

public void testExchange001()

{

// get

MultiValueMap<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同步调用

*/

@Test

public void testExchange002()

{

// get

Mono<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 post

MultiValueMap<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同步调用

*/

@Test

public 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同步调用

*/

@Test

public 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同步调用

*/

@Test

public 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同步调用

*

*/

@Test

public 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

*

*/

@Test

public 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同步调用

*

*/

@Test

public 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同步调用

*

*/

@Test

public 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

*/

@Test

public void testJsonBody002()

throws IOException

{

Mono<String> mono;

int num = RandomUtils.nextInt(1, 4);

switch (num)

{

case 1: // 方式1,javaBean

SearchReq 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,HashMap

Map<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同步调用

*

*/

@Test

public 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同步调用

*

*/

@Test

public 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-



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。