Spring Boot(13)——使用RestTemplate

使用RestTemplate

RestTemplate是Spring Web模塊提供的作爲客戶端按照Rest規範進行Http請求的工具。Spring Boot也提供了對它的自動配置,Spring Boot不是直接的配置好RestTemplate對象,而是由org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration配置類自動配置一個org.springframework.boot.web.client.RestTemplateBuilder對象,需要使用RestTemplate時可以注入RestTemplateBuilder對象,通過其build方法可以構建一個RestTemplate對象。比如下面的代碼中SomeService會被掃描爲一個Spring bean,其構造函數需要一個RestTemplateBuilder對象,Spring將自動爲其注入該對象,在構造函數中通過注入的RestTemplateBuilder對象創建了一個RestTemplate對象,並把它保存起來,之後就可以在其它地方使用了,比如getSomething()

@Component
public class SomeService {

    private final RestTemplate restTemplate;
    
    public SomeService(RestTemplateBuilder restTemplateBuilder) {
        this.restTemplate = restTemplateBuilder.build();
    }
    
    public String getSomething() {
        String content = this.restTemplate.getForObject("https://www.baidu.com", String.class);
        return content;
    }
    
}

關於RestTemplate的用法可以參考http://elim.iteye.com/blog/2427553

自定義配置

RestTemplateBuilder對象還提供了一系列的配置方法,可以方便的進行一些自定義,每個方法的調用都會返回一個全新的RestTemplateBuilder對象。所以在使用的時候可以放心的進行使用,而不必擔心會影響到其它使用的地方。

配置HttpMessageConverter

可以通過messageConverters()指定需要應用的HttpMessageConverter。

restTemplateBuilder.messageConverters(new StringHttpMessageConverter(Charset.forName("UTF-8")));
this.restTemplate = restTemplateBuilder.build();

上面的方式會是覆蓋式的,可以應用additionalMessageConverters方法進行追加。

restTemplateBuilder.additionalMessageConverters(new StringHttpMessageConverter(Charset.forName("UTF-8")));
this.restTemplate = restTemplateBuilder.build();

另外,如果沒有定義自己的org.springframework.boot.autoconfigure.http.HttpMessageConverters bean,Spring Boot默認會在創建RestTemplateBuilder時應用bean容器中能發現的所有HttpMessageConverter類型的bean。所以如果我們有一個自定義的HttpMessageConverter需要應用到RestTemplate,只需要把它定義爲Spring bean即可。

配置攔截器

RestTemplate其實還可以了一個ClientHttpRequestInterceptor接口,可以在發起請求前後對請求內容或響應內容進行攔截處理。可以實現自己的ClientHttpRequestInterceptor,然後通過interceptors()進行應用。

restTemplateBuilder.interceptors(new TestInterceptor());
this.restTemplate = restTemplateBuilder.build();

上面的方式也是覆蓋式的,可以通過additionalInterceptors()進行追加。

restTemplateBuilder.additionalInterceptors(new TestInterceptor());
this.restTemplate = restTemplateBuilder.build();

Spring已經提供了一個用來進行Http Basic認證的攔截器,叫BasicAuthorizationInterceptor,它可以在每次請求的時候附加上需要用來認證的用戶名和密碼。

restTemplateBuilder.interceptors(new BasicAuthorizationInterceptor("username", "password"));
this.restTemplate = restTemplateBuilder.build();

RestTemplateBuilder中提供了配置BasicAuthorizationInterceptor的簡化方式,它開放了一個basicAuthorization()

restTemplateBuilder.basicAuthorization("username", "password");
this.restTemplate = restTemplateBuilder.build();

配置超時時間

可以通過setConnectTimeout()指定建立連接超時時間,通過setReadTimeout()指定獲取響應結果的超時時間,單位都是毫秒。

restTemplateBuilder.setConnectTimeout(10 * 1000).setReadTimeout(20 * 1000);
this.restTemplate = restTemplateBuilder.build();

更多配置信息可以參考RestTemplateBuilder的API文檔。

ClientHttpRequestFactory

在非Spring Boot環境下使用RestTemplate時,默認的ClientHttpRequestFactory是基於JDK實現的SimpleClientHttpRequestFactory。Spring Boot中RestTemplateBuilder默認會檢測Classpath路徑下的ClientHttpRequestFactory實現,如果擁有Apache HttpComponents的org.apache.http.client.HttpClient類則會使用org.springframework.http.client.HttpComponentsClientHttpRequestFactory,擁有okhttp3.OkHttpClient則會使用org.springframework.http.client.OkHttp3ClientHttpRequestFactory。如果都沒有則會使用基於JDK實現的SimpleClientHttpRequestFactory。可以通過detectRequestFactory(false)關閉這種默認檢測的機制。

restTemplateBuilder.detectRequestFactory(false);

可以通過requestFactory()強制指定使用某個實現,下面的代碼就配置了將強制使用一個進行了自定義的HttpComponentsClientHttpRequestFactory對象。它擁有一個重載的可以指定ClientHttpRequestFactory實現類的方法,使用該方法將採用指定實現類的默認配置。

RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(10*1000).setConnectionRequestTimeout(30*1000).build();
HttpClient httpClient = HttpClientBuilder.create().setMaxConnPerRoute(20).setMaxConnTotal(50).setDefaultRequestConfig(requestConfig).build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
restTemplateBuilder.requestFactory(() -> requestFactory);

通用的自定義配置

上面介紹的自定義配置都是基於某個RestTemplateBuilder進行的,一個應用中如果有多個地方需要使用RestTemplateBuilder構建RestTemplate時,如果某些自定義配置是通用的,每個地方都寫一遍會比較麻煩。Spring Boot提供了一個RestTemplateBuilder接口,通過它可以對創建好的RestTemplate進行一些自定義配置。

@FunctionalInterface
public interface RestTemplateCustomizer {

    /**
     * Callback to customize a {@link RestTemplate} instance.
     * @param restTemplate the template to customize
     */
    void customize(RestTemplate restTemplate);

}

Spring Boot在創建RestTemplateBuilder時,默認會把bean容器中定義的RestTemplateCustomizer都應用到RestTemplateBuilder中,也就是說如果需要對RestTemplate進行自定義,可以把自定義的RestTemplateCustomizer實現類定義爲一個Spring bean。

(注:本文是基於Spring Boot 2.0.3所寫)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章