WebClient使用
引言
Spring Framework 5 包括一个新的 spring-webflux 模块。该模块包含对响应式 HTTP 和 WebSocket 客户端的支持,以及对REST,HTML浏览器和 WebSocket风格交互的响应式服务器Web应用程序的支持。本文主要介绍WebClient的使用,包括通过WebClient请求接口及实现接口的文件上传下载。
1.引入依赖
在pom.xml中引入WebClient所需的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.projectreactor</groupId>
<artifactId>reactor-spring</artifactId>
<version>1.0.1.RELEASE</version>
</dependency>
2.一个简单的请求示例
请求百度首页示例
// 1.创建WebClient实例
WebClient webClient = WebClient
.builder()
.baseUrl("https://www.baidu.com")
.build();
// 2.通过通过retrieve()请求并获得响应
Mono<String> bodyToMono = webClient
.get()
.retrieve()
// 将请求结果处理为String类型
.bodyToMono(String.class);
log.info("请求返回的数据内容:{}", bodyToMono.block());
3.WebClient配置
在创建WebClient时可对一些变量进行默认设置
WebClient client3 = WebClient
.builder()
.baseUrl("http://localhost:8080")
.defaultCookie("cookieKey", "cookieValue")
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.defaultUriVariables(Collections.singletonMap("url", "http://localhost:8080"))
.build();
也可在发起请求时填入cookie、header等参数
webClient
.get()
.uri("https://www.baidu.com")
.cookie("cookieKey", "cookieValue")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.retrieve();
4.在请求中传参
在日常使用中传递参数的方法
WebClient webClient = WebClient.create();
Mono<String> bodyToMono = webClient.post()
.uri(uriBuilder ->
uriBuilder
.scheme("https")
.host("localhost:8080")
.path("/api/test")
.queryParam("id", "123")
.queryParam("invalid", "invalid123")
.build()
)
// requestbody,也可以使用MultiValueMap<String, String> map = new LinkedMultiValueMap<>(),传入参数,发起form提交。或直接使用HashMap传参
.syncBody(new Student())
.retrieve()
.bodyToMono(String.class);
5.设置连接超时时间
设置请求超时时间
TcpClient tcpClient = TcpClient
.create()
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
.doOnConnected(connection -> {
connection.addHandlerLast(new ReadTimeoutHandler(5000, TimeUnit.MILLISECONDS));
connection.addHandlerLast(new WriteTimeoutHandler(5000, TimeUnit.MILLISECONDS));
});
WebClient client = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient)))
.build();
6.文件上传
上传文件代码
HttpHeaders headers = new HttpHeaders();
headers.add("content-type", "application/x-www-form-urlencoded");
HttpEntity<ClassPathResource> entity = new HttpEntity<>(new ClassPathResource("a.txt"), headers);
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
parts.add("file", entity);
Mono<String> bodyToMono = WebClient.create().post()
.uri("http://localhost:8080/upload")
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData(parts))
.retrieve().bodyToMono(String.class);
7.文件下载
通过将.retrieve()方法换成.exchange(),可以获取到响应的头信息、Cookie等信息,与restTemplate相似。
Mono<ClientResponse> responseMono = WebClient.create().get()
.uri("http://localhost:8080/file/download")
.accept(MediaType.APPLICATION_OCTET_STREAM)
.exchange();
ClientResponse response = responseMono.block();
// 可从headers中获取filename等信息
ClientResponse.Headers headers = response.headers();
Resource resource = response.bodyToMono(Resource.class).block();
// 获取文件流
InputStream inputStream = resource.getInputStream();
8.WebTestClient
The WebTestClient is the main entry point for testing WebFlux server endpoints. It has a very similar API to the WebClient, and it delegates most of the work to an internal WebClient instance focusing mainly on providing a test context. The DefaultWebTestClient class is a
single interface implementation.
主要意思是WebTestClient用于测试WebFlux服务器端点,他和WebClient相似,且将大部分工作委托给了内部的WebClient,主要用于测试上下文,此部分后期在单独整理。