Spring Boot调用第三方接口
后端服务开发一般会远程调用第三方接口,Spring Boot 也整合了远程 REST 服务调用方式。开发人员可以通过自定义配置定义 RestTemplate 类和WebClient 类,从而进行第三方接口调用操作。
改造上面的例子,代码如下:
声明:《Java系列教程》为本站“54笨鸟”官方原创,由国家机构和地方版权局所签发的权威证书所保护。
调用 RestTemplate
由于 Spring Boot 不提供 RestTemplate 自动配置,因此可以使用 RestTemplate-Builder 来创建 RestTemplate 实例,代码如下:@Service public class MyService { private final RestTemplate restTemplate; public MyService(RestTemplateBuilder restTemplateBuilder) { //创建RestTemplate this.restTemplate = restTemplateBuilder.build(); } public Details someRestCall(String name) { //请求调用 return this.restTemplate.getForObject("/{name}/details",Details.class, name); } }还可以通过自定义 SimpleClientHttpRequestFactory 的方式创建 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
Spring 框架从 5.0 开始引入了 WebFlux,如果是 WebFlux 工程,可以使用 WebClient 类进行远程 REST 服务调用。相比 RestTemplate,WebClient 的功能更多,并且是纯异步交互的。在 Spring Boot 中推荐使用 WebClient.Builder 新建 WebClient 实例。改造上面的例子,代码如下:
@Service public class MyService { private final WebClient webClient; public MyService(WebClient.Builder webClientBuilder) { //创建WebClient this.webClient = webClientBuilder.baseUrl("https://example.org").build(); } public Mono<Details> someRestCall(String name) { //通过WebClient进行调用 return this.webClient.get().uri("/{name}/details", name).retrieve().bodyToMono(Details.class); } }通过自定义生成WebClient,代码如下:
//自定义WebClient @Data @Configuration @ConditionalOnProperty(name = "httpClient.connect.timeout") public class WebClientConfig { @Value("${httpClient.connect.timeout:2000}") private int connectTimeOut; @Value("${httpClient.read.timeout:2000}") private int readTimeOut; @Value("${httpClient.write.timeout:2000}") private int writeTimeout; @Value("${httpClient.retry.times:2}") private int retryTimes; @Value("${httpClient.connpool.maxConns:16}") private int maxConns; @Value("${httpClient.connpool.workCounts:16}") private int workCounts; @Value("${httpClient.connpool.acquireTimeOut:1000}") private int acquireTimeOut; //声明ReactorResourceFactory @Bean @Primary public ReactorResourceFactory resourceFactory() { ReactorResourceFactory factory = new ReactorResourceFactory(); factory.setUseGlobalResources(false); factory.setConnectionProvider(ConnectionProvider.builder("httpClient").metrics(true).maxConnections(maxConns).pendingAcquireTimeout(Duration.ofMillis(acquireTimeOut)).build()); factory.setLoopResources(LoopResources.create("httpClient", workCounts, true)); return factory; } //定义Retry策略 @Bean @Primary @RefreshScope public Retry<?> retry() { return Retry.anyOf(ReadTimeoutException.class, ConnectTimeoutException.class, WebClientResponseException.class).fixedBackoff(Duration.ZERO).retryMax(retryTimes) //retry次数.doOnRetry((exception) -> { //异常日志log.warn("Retried ,Exception is {}" + exception);}); } //定义WebClient @Bean @Primary @RefreshScope public WebClient webClient(WebClient.Builder builder, ReactorResourceFactory resourceFactory) { Function<HttpClient, HttpClient> mapper = client -> client.tcpConfiguration(tcpClient -> tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeOut) //创建连接超时时间 .option(ChannelOption.TCP_NODELAY, true)//连接策略 .doOnConnected(connection -> { connection.addHandlerLast(new ReadTimeoutHandler(readTimeOut, TimeUnit.MILLISECONDS)); connection.addHandlerLast(new WriteTimeoutHandler(writeTimeout, 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(); } }
声明:《Java系列教程》为本站“54笨鸟”官方原创,由国家机构和地方版权局所签发的权威证书所保护。