使用 HttpClient 取代原本的連線方式,因預設使用 Java HttpConnection,來調用遠端服務,HttpClient 擴展了更多的功能,因此 EP 28-1 增加了範例,並透過 JUnit 5 單元測試來驗證產出結果。
Table of Contents
Toggle前言
RestTemplate 是一個提供 REST 規範 HTTP 請求的工具,封裝了複雜的操作,一系列的 getXXX 、postXXX 、putXXX 、deleteXXX 等方法,讓操作更方便,以及更通用的 exchange 、 execute 等方法,使得調用流程變得更加精簡,便於日後管理與維護,整合 HttpClient 之後,將會使得它的功能更加強大。
HttpClient RestTemplate
檔案目錄
./
+- build.gradle
+- src
+- main
+- java
+- org
+- ruoxue
+- spring_boot_168
+- config
+- HttpClientRestTemplateConfig.java
closeableHttpClient
參考注入。
@Autowired
@Qualifier("closeableHttpClient")
private CloseableHttpClient closeableHttpClient;
httpComponentsClientHttpRequestFactory
由 closeableHttpClient,建立客端請求工廠。
@Bean(name = "httpComponentsClientHttpRequestFactory")
public ClientHttpRequestFactory httpComponentsClientHttpRequestFactory() {
return new HttpComponentsClientHttpRequestFactory(closeableHttpClient);
}
httpClientRestTemplate
Rest 操作樣板,由客端請求工廠建立,並設定轉換器。
@Bean(name = "httpClientRestTemplate")
public RestTemplate restTemplate(
@Qualifier("httpComponentsClientHttpRequestFactory") ClientHttpRequestFactory clientHttpRequestFactory) {
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
restTemplate.getMessageConverters().add(new TextHttpMessageConverter());
return restTemplate;
}
TextHttpMessageConverter
MediaType 轉換器加上 plain 、 html 。
public class TextHttpMessageConverter extends MappingJackson2HttpMessageConverter {
public TextHttpMessageConverter() {
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.TEXT_PLAIN);
mediaTypes.add(MediaType.TEXT_HTML);
setSupportedMediaTypes(mediaTypes);
}
}
HttpClientRestTemplateConfig.java
注入 CloseableHttpClient,如何設定,參考此篇:
package org.ruoxue.spring_boot_168.config;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import lombok.extern.slf4j.Slf4j;
@Configuration
@Slf4j
public class HttpClientRestTemplateConfig {
@Autowired
@Qualifier("closeableHttpClient")
private CloseableHttpClient closeableHttpClient;
@Bean(name = "httpComponentsClientHttpRequestFactory")
public ClientHttpRequestFactory httpComponentsClientHttpRequestFactory() {
return new HttpComponentsClientHttpRequestFactory(closeableHttpClient);
}
@Bean(name = "httpClientRestTemplate")
public RestTemplate restTemplate(
@Qualifier("httpComponentsClientHttpRequestFactory") ClientHttpRequestFactory clientHttpRequestFactory) {
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
restTemplate.getMessageConverters().add(new TextHttpMessageConverter());
return restTemplate;
}
public class TextHttpMessageConverter extends MappingJackson2HttpMessageConverter {
public TextHttpMessageConverter() {
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.TEXT_PLAIN);
mediaTypes.add(MediaType.TEXT_HTML);
setSupportedMediaTypes(mediaTypes);
}
}
}
測試 JUnit 5
HttpClientRestTemplateConfigTest.java
新增單元測試,驗證是否符合預期 。
package org.ruoxue.spring_boot_168.config;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.ruoxue.spring_boot_168.Application;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = Application.class)
public class HttpClientRestTemplateConfigTest {
@Autowired
private HttpClientRestTemplateConfig config;
@Test
public void config() {
assertNotNull(config);
}
}
config
測試方法上點右鍵執行 Run As -> JUnit Test ,查看 console 。
2022-07-05T01:47:17.951+0800 [main] INFO logStarted:59 - Started in 11.399 seconds (JVM running for 12.539)
心得分享
HttpClient 可以做為連接池,而發送消息的工具類可以使用 RestTemplate ,除了支援 HttpClient 之外,也可採用 Netty 、 OkHttp 作為 HTTP 連線工具,實現遠端調用第三方 RESTful 接口,多樣化的連線方式,提供給開發者更多的選擇。
Client Http
除了 HttpClient 之外,還有採用異步的方式, AsyncHttpClient 可以評估使用。