Java的HTTP客户端介绍
- 阻塞式 RestTemplate
- 响应式 WebClient
WebClient
public interface WebClient
非阻塞,响应式的HTTP请求客户端
可以通过静态方法 create()
, create(String)
, builder()
构造实例。
@Bean
public WebClient webClient() {
return WebClient.builder()
.baseUrl(props.getFileServerUrl())
.build();
}
response
request
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
使用WebClient
- HTTP Headers
webClient
.post()
.uri(uriBuilder ->
uriBuilder.pathSegment("users", "{userId}")
.build(userId))
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
- Request Body
webClient
.post()
.uri(uriBuilder ->
uriBuilder.pathSegment("users", "{userId}")
.build(userId))
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(userStr)
- 发送请求
Mono<User> response = webClient
.post()
.uri(uriBuilder ->
uriBuilder.pathSegment("users", "{userId}")
.build(userId))
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromPublisher(Mono.just(userObj)))
.retrieve()
.bodyToMono(User.class);
Mono<ClientResponse> response = webClient
.post()
.uri(uriBuilder ->
uriBuilder.pathSegment("users", "{userId}")
.build(userId))
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromPublisher(Mono.just(userObj)))
.exchangeToMono(result -> {
if (result.statusCode()
.equals(HttpStatus.OK)) {
return result.bodyToMono(User.class);
} else if (result.statusCode()
.is4xxClientError()) {
return Mono.error(new ApplicationException(ERROR_MSG))
}
});
应用
- 下载文件,使用DataBuffer作为数组缓冲
Mono<DataBuffer> dataBuffer = webClient
.get()
.uri("/largefiles/1")
.retrieve()
.bodyToMono(DataBuffer.class);
DataBufferUtils.write(dataBuffer, destination,
StandardOpenOption.CREATE)
.share().block();
- 设置DataBuffer的容量限制
public WebClient webClientWithLargeBuffer() {
return WebClient.builder()
.baseUrl("http://localhost:8182")
.exchangeStrategies(ExchangeStrategies.builder()
.codecs(configurer ->
configurer.defaultCodecs()
.maxInMemorySize(2 * 1024)
)
.build())
.build();
}
- 设置超时时间
WebClient.create(GET_STUDENTS_URL)
.get()
.retrieve()
.bodyToFlux(Student.class)
.timeout(Duration.ofSeconds(10));
- 重试次数
WebClient.create()
.get()
.uri(GET_STUDENTS_URL)
.retrieve()
.bodyToFlux(Student.class)
.retry(3L);