HttpClient RestTemplate - Spring Boot 168 EP 28-1

HttpClient RestTemplate – Spring Boot 168 EP 28-1

使用 HttpClient 取代原本的連線方式,因預設使用 Java HttpConnection,來調用遠端服務,HttpClient 擴展了更多的功能,因此 EP 28-1 增加了範例,並透過 JUnit 5 單元測試來驗證產出結果。

前言

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 可以評估使用。

發佈留言