Spring Boot RestTemplate - Spring Boot 168 EP 28

Spring Boot RestTemplate – Spring Boot 168 EP 28

預設使用 Java HttpConnection,調用遠端服務,也可以使用 ClientHttpRequestFactory 指定不同的 HTTP 連接方式, EP 28 增加了範例,並透過 JUnit 5 單元測試來驗證產出結果。

前言

RestTemplate 是一個提供 REST 規範 HTTP 請求的工具,封裝了複雜的操作,一系列的 getXXX 、postXXX 、putXXX 、deleteXXX 等方法,讓操作更方便,以及更通用的 exchange 、 execute 等方法,使得調用流程變得更加精簡,便於日後管理與維護。

Spring Boot RestTemplate

檔案目錄

./
   +- build.gradle
       +- src
           +- main
               +- resources
               |   +- application.properties
               +- java
                   +- org
                       +- ruoxue
                           +- spring_boot_168
                               +- config
                                   +- RestTemplateConfig.java 

設定

application.properties

增加 HttpClient 設定。

http-client.connectTimeout=3000
http-client.socketTimeout=3000

simpleClientHttpRequestFactory

簡單客端請求工廠,設定 timeout。

	@Bean(name = "simpleClientHttpRequestFactory")
	public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
		SimpleClientHttpRequestFactory simpleClientHttpRequestFactory = new SimpleClientHttpRequestFactory();
		simpleClientHttpRequestFactory.setConnectTimeout(connectTimeout);
		simpleClientHttpRequestFactory.setReadTimeout(socketTimeout);
		log.info("connectTimeout: ", connectTimeout);
		log.info("socketTimeout: ", socketTimeout);
		return simpleClientHttpRequestFactory;
	}

restTemplate

Rest 操作樣板,由簡單客端請求工廠建立,並設定轉換器。

	@Bean(name = "restTemplate")
	public RestTemplate restTemplate(
			@Qualifier("simpleClientHttpRequestFactory") 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);
		}
	}	

RestTemplateConfig.java

package org.ruoxue.spring_boot_168.config;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
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.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import lombok.extern.slf4j.Slf4j;

@Configuration
@Slf4j
public class RestTemplateConfig {

	@Value("${http-client.connectTimeout}")
	private int connectTimeout;

	@Value("${http-client.socketTimeout}")
	private int socketTimeout;

	@Bean(name = "simpleClientHttpRequestFactory")
	public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
		SimpleClientHttpRequestFactory simpleClientHttpRequestFactory = new SimpleClientHttpRequestFactory();
		simpleClientHttpRequestFactory.setConnectTimeout(connectTimeout);
		simpleClientHttpRequestFactory.setReadTimeout(socketTimeout);
		log.info("connectTimeout: ", connectTimeout);
		log.info("socketTimeout: ", socketTimeout);
		return simpleClientHttpRequestFactory;
	}

	@Bean(name = "restTemplate")
	public RestTemplate restTemplate(
			@Qualifier("simpleClientHttpRequestFactory") 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

RestTemplateConfigTest.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 RestTemplateConfigTest {

	@Autowired
	private RestTemplateConfig config;

	@Test
	public void config() {
		assertNotNull(config);
	}
}

RestTemplate POST config

測試方法上點右鍵執行 Run As -> JUnit Test ,查看 console 。

2022-07-05T22:01:35.314+0800 [main] INFO simpleClientHttpRequestFactory:33 - connectTimeout: 
2022-07-05T22:01:35.314+0800 [main] INFO simpleClientHttpRequestFactory:34 - socketTimeout: 

心得分享

RestTemplate getForObjet

提供了多種簡潔方便的調用遠端服務方法,發送 JSON 格式的請求,取得回傳資訊,操作起來比 HttpClient 或 OKHttp 更加方便許多,程式碼也更為精簡。

發佈留言