Spring中RestTemplate進行Http調用


Spring中的RestTemplate類源自spring-web,http調用中設置超時時間、設置連接池管理等非常重要,保證了系統的可用性,避免了長時間連接不上或者等待數據返回,拖垮系統。

現貼出工作上關於RestTemplate的標准配置,設置了超時時間、連接池等,開箱即用。

package com.pab.bloan.charge.app.common.config;

import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.SocketConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Configuration
public class RestTemplateConfig {

    private static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 100;

    private static final int DEFAULT_MAX_CONNECTIONS_PER_ROUTE = 10;

    private static final int DEFAULT_MAX_TIME_OUT = 3000;

    @Value("${rest-template.timeout:3000}")
    private int defaultTimeOut;

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate(httpRequestFactory());
        List<HttpMessageConverter<?>> converters = new ArrayList<>();
        FastJsonHttpMessageConverter jacksonMessageConverter = new FastJsonHttpMessageConverter();
        converters.add(jacksonMessageConverter);
        restTemplate.setMessageConverters(converters);
        return restTemplate;
    }

    @Bean
    public ClientHttpRequestFactory httpRequestFactory() {
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        RequestConfig requestConfig = RequestConfig.custom()
                // 連接超時
                .setConnectTimeout(defaultTimeOut)
                // 排隊超時
                .setConnectionRequestTimeout(defaultTimeOut)
                // 數據讀取超時
                .setSocketTimeout(defaultTimeOut)
                .build();
        requestFactory.setConnectTimeout(defaultTimeOut);
        requestFactory.setReadTimeout(defaultTimeOut);
        SocketConfig socketConfig = SocketConfig
                .custom()
                .setSoKeepAlive(false)
                .setTcpNoDelay(true)
                .build();
        PoolingHttpClientConnectionManager pm = new PoolingHttpClientConnectionManager();
        pm.setDefaultSocketConfig(socketConfig);
        pm.closeIdleConnections(DEFAULT_MAX_TIME_OUT, TimeUnit.MICROSECONDS);
        pm.setMaxTotal(DEFAULT_MAX_TOTAL_CONNECTIONS);
        pm.setDefaultMaxPerRoute(DEFAULT_MAX_CONNECTIONS_PER_ROUTE);
        CloseableHttpClient httpClient = HttpClientBuilder.create()
                .setDefaultRequestConfig(requestConfig)
                .setConnectionManager(pm)
                .build();
        requestFactory.setHttpClient(httpClient);
        return requestFactory;
    }
}

使用示例(代碼中將相關的請求url、請求參數、響應參數,替換掉即可):

/**
     * 調用渠道查詢客戶經理名單接口
     * @param saleManagerRequest
     * @return
     */
    private SaleManagerResponse requestQDSaleManagerApi(SaleManagerRequest saleManagerRequest) {
        // 調用外聯額度變更接口
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        ResponseEntity<SaleManagerResponse> responseEntity =
                restTemplate.postForEntity(accessGatewayService.getAccessGatewayRequestUrl(qdSaleManagerSearchUrl),
                        new HttpEntity<>(saleManagerRequest, headers), SaleManagerResponse.class);

        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            SaleManagerResponse saleManagerResponse = responseEntity.getBody();
            if (saleManagerResponse != null
                    && Response.SUCCESS.equals(saleManagerResponse.getResponseCode())) {
                return saleManagerResponse;
            } else {
                log.error("request destination error:[requestUrl:{}; request:{}; response:{}]",
                        new Object[]{qdSaleManagerSearchUrl, saleManagerRequest, saleManagerResponse});
                throw new BusinessException("調用渠道查詢客戶經理名單接口異常");
            }
        } else {
            throw new BusinessException("調用渠道查詢客戶經理名單接口網絡不可達");
        }
    }

標准化代碼,用起來美滋滋。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM