调用RestTemplate
由于SpringBoot不提供自动配置 可用RestTemplate-Builder 来创建RestTemplate实例 代码如下
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class MyService {
private final RestTemplate restTempalte;
public MyService(RestTemplate restTempalte) {
//创建RestTemplate
this.restTempalte = restTempalte;
}
public Details someRestCall(String name){
//请求调用
return this.restTempalte.getForObject("/{name}/details",Details.class, name);
}
}
通过自定义的SimpleCilentHttpRequestFactory的方式创建RestTemplate
package com.example.springboot.controller;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
return new RestTemplate(factory); //创建RestTemplate
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(15000); //设置连接超时
factory.setReadTimeout(5000); //设置读取超时
return factory;
}
}
调用WebClient
import org.springframework.stereotype.Service;
import javax.xml.soap.Detail;
@Service
public class MyService {
private final WebClient webClient;
public MyService(WebClient.Builder webClientBuilder) {
//创建WebClient
this.webClient=webClientBuilder.baseUrl("https://example.org").build();
}
public Mone<Details> someRestCall(String name){
//通过WebClient调用
return this.WebClient.get().uri("/{name}/details",name).retrieve().bodyToMon(Details.class);
}
}
package com.example.springboot.controller;
import io.netty.channel.ChannelOption;
import io.netty.channel.ConnectTimeoutException;
import io.netty.handler.timeout.ReadTimeoutException;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.client.reactive.ClientHttpConnector;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.http.client.reactive.ReactorResourceFactory;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientResponseException;
import reactor.netty.resources.ConnectionProvider;
import reactor.netty.resources.LoopResources;
import reactor.retry.Retry;
import reactor.netty.http.client.HttpClient;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
@Configuration
public class WebClientConfig {
@Bean
@Primary
public ReactorResourceFactory resourceFactory() {
ReactorResourceFactory factory = new ReactorResourceFactory();
factory.setUseGlobalResources(false);
factory.setConnectionProvider(ConnectionProvider.builder("httpClient").metrics(true).maxConnections(16)
.pendingAcquireTimeout(Duration.ofMillis(1000)).build());
factory.setLoopResources(LoopResources.create("httpClient", 16, true));
return factory;
}
//定义Retry策略
@Bean
@Primary
public Retry<?> retry() {
return Retry.anyOf(ReadTimeoutException.class, ConnectTimeoutException.class, WebClientResponseException.class)
.fixedBackoff(Duration.ZERO)
.retryMax(2) //retry次数
.doOnRetry((exception) -> { //异常日志
});
}
//定义WebClient
@Bean
@Primary
public WebClient webClient(WebClient.Builder builder, ReactorResourceFactory resourceFactory) {
Function<HttpClient, HttpClient> mapper = client ->
client.tcpConfiguration(tcpClient ->
tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2000) //创建连接超时时间
.option(ChannelOption.TCP_NODELAY, true)
.doOnConnected(connection -> { //链接策略
connection.addHandlerLast(new ReadTimeoutHandler(2000, TimeUnit.MILLISECONDS));
connection.addHandlerLast(new WriteTimeoutHandler(2000, TimeUnit.MILLISECONDS));
}))
.headers(headerBuilder -> { //设置header属性
headerBuilder.set("Accept-Charset", "utf-8");
headerBuilder.set("Accept-Encoding", "gzip, x-gzip, deflate");
headerBuilder.set("ContentType", "text/plain; charset=utf-8");
}).keepAlive(true);
ClientHttpConnector connector = new ReactorClientHttpConnector(resourceFactory, mapper);
return builder.clientConnector(connector).build();
}
}