zoukankan      html  css  js  c++  java
  • 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("调用渠道查询客户经理名单接口网络不可达");
            }
        }

    标准化代码,用起来美滋滋。

  • 相关阅读:
    C#8.0新特性
    C#7.0新特性
    C#6.0新特性
    C#6.0到C#8.0的新特性
    纪念博客开通的6月29日
    什么是开发中经常说的'POCO'
    什么时候用Model,什么时候用Entity?
    C#数组的 Length 和 Count()
    C#中foreach的实现原理
    Windows Server 2012 R2远程桌面默认端口修改
  • 原文地址:https://www.cnblogs.com/dushenzi/p/10636398.html
Copyright © 2011-2022 走看看