文章目录
- 一、概述
- 二、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);
}
}
@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"?>
<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可以轻松实现。 -->
<transformer
implementation="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 : 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"?>
<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 : 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-