RestTemplate推送数据无响应的解决办法

原创 2018年04月17日 14:57:56

导读

  • A平台在给其他平台推送数据时,A平台调用其他平台接口成功,但无返回结果,导致消费机数据不消费。

逻辑分析

  • 应该有推送多长时间无返回结果就为推送失败,这样的逻辑。

代码分析

推送源码

RestTemplate restTemplate = new RestTemplate();
ResponseResult responseResult = restTemplate.postForObject(syncUrl, formEntity, ResponseResult.class);
  • 感觉restTemplate有配置,但是查看了RestTemplate类,并没有相关配置。经过百度发现:SimpleClientHttpRequestFactory类。

SimpleClientHttpRequestFactory 部分源码

public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory, AsyncClientHttpRequestFactory {
    private static final int DEFAULT_CHUNK_SIZE = 4096;
    private Proxy proxy;
    private boolean bufferRequestBody = true;
    private int chunkSize = 4096;
    private int connectTimeout = -1;
    private int readTimeout = -1;
    private boolean outputStreaming = true;
    private AsyncListenableTaskExecutor taskExecutor;
    //...
    public void setConnectTimeout(int connectTimeout) {
        this.connectTimeout = connectTimeout;
    }
    //...
    public void setReadTimeout(int readTimeout) {
        this.readTimeout = readTimeout;
    }
}
  • 发现有 setConnectTimeout 和 setReadTimeout 方法,且默认值为 -1。进而猜测是这里导致一直卡死。

修改推送代码(方式一)

SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(20000);
        requestFactory.setReadTimeout(20000);
        RestTemplate restTemplate = new RestTemplate(requestFactory);

思考

  • 有没有配置文件可以进行配置,而不用每次set配置呢?

编写配置 RestTemplateConfiguration 类 (方式二)

@Configuration
@ConditionalOnClass(value = {RestTemplate.class, HttpClient.class})
public class RestTemplateConfiguration {
    @Value("${remote.maxTotalConnect:0}")
    private int maxTotalConnect; //连接池的最大连接数默认为0
    @Value("${remote.maxConnectPerRoute:200}")
    private int maxConnectPerRoute; //单个主机的最大连接数
    @Value("${remote.connectTimeout:2000}")
    private int connectTimeout; //连接超时默认2s
    @Value("${remote.readTimeout:30000}")
    private int readTimeout; //读取超时默认30s

    private ClientHttpRequestFactory createFactory() {
        if (this.maxTotalConnect <= 0) {
            SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
            factory.setConnectTimeout(this.connectTimeout);
            factory.setReadTimeout(this.readTimeout);
            return factory;
        }
        HttpClient httpClient = HttpClientBuilder.create().setMaxConnTotal(this.maxTotalConnect)
                .setMaxConnPerRoute(this.maxConnectPerRoute).build();
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(
                httpClient);
        factory.setConnectTimeout(this.connectTimeout);
        factory.setReadTimeout(this.readTimeout);
        return factory;
    }

    @Bean
    @ConditionalOnMissingBean(RestTemplate.class)
    public RestTemplate getRestTemplate() {
        RestTemplate restTemplate = new RestTemplate(this.createFactory());
        List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();

        HttpMessageConverter<?> converterTarget = null;
        for (HttpMessageConverter<?> item : converterList) {
            if (StringHttpMessageConverter.class == item.getClass()) {
                converterTarget = item;
                break;
            }
        }
        if (null != converterTarget) {
            converterList.remove(converterTarget);
        }
        converterList.add(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));

        converterList.add(new FastJsonHttpMessageConverter4());
        return restTemplate;
    }

}

该配置文件的使用

@Service
@Import({RestTemplateConfiguration.class})
public class AServiceImpl implements AService {
    private final ADao aDao;
    //...
}
  • 本人原创,请勿抄袭,如果喜欢请转载,谢谢。
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010318957/article/details/79974920

RestTemplate使用

概述RestTemplate是spring内置的http请求封装,在使用spring的情况下,http请求直接使用RestTemplate是不错的选择。Rest服务端使用RestTemplate发起h...
  • clj198606061111
  • clj198606061111
  • 2017-04-18 13:56:24
  • 10313

RestTemplate请求,响应数据太大导致eof

public static String requstRestPost(String url, String param) { HttpHeaders requestHeaders = new Ht...
  • ruben95001
  • ruben95001
  • 2017-02-22 16:02:28
  • 2501

Spring通过RestTemplate传送数据

今天调接口的时候用到了RestTemplate调用,但是传过去的字符编码却是ISO-8859-1,百度一下,发现Resttemplate默认编码就是ISO-8859-1,传数据前需要设置一下 具体设...
  • ln865709215
  • ln865709215
  • 2016-11-14 09:37:53
  • 683

Post Json 例子 Spring Rest Template & HttpClient

package com.lee; import static java.lang.System.out; import java.io.Serializable; import ...
  • ppby2002
  • ppby2002
  • 2014-03-13 12:04:35
  • 5671

RestTemplate使用gzip压缩调用接口

RestTemplate使用gzip压缩调用接口,首先要开启Apache或nginx的gzip支持。开启gzip可以自己百度一下。我配置了Apache的gzip支持,但是只有页面的可以压缩,调用接口的...
  • liangtll
  • liangtll
  • 2017-01-19 15:56:24
  • 1384

Spring RestTemplate get方式发送数据服务器端拿到为空

在使用Spring restTemplate类测试url接口的时候,使用get请求发送参数服务器端拿不到请求数据。 请求代码是这样的  Map map = new HashMap(); ...
  • u013803262
  • u013803262
  • 2017-09-08 19:17:51
  • 422

使用 RestTemplate 发送 post 请求后返回 json 中 ":" 变成 "=" 的解决办法

打算使用 RestTemplate 替换别人封装的 HttpClient ,但是在测试的过程中发现了一个问题。 发现返回的 json 的格式中,HttpClient 返回的 json 是 正常的...
  • HeatDeath
  • HeatDeath
  • 2018-02-24 14:57:14
  • 240

通过RestTemplate调用外部服务

调用外部接口: 通过RestTemplate调用外部服务 (使用高德地图API实现ip定位及天气查询)   1.导入需要的jar包 可以通过Apache HttpClient官网下载...
  • Ned_mahone
  • Ned_mahone
  • 2017-12-22 22:56:58
  • 278

restTemplate获取gizp字符串数据和解码

前提服务器开启gzip支持 public static void main(String[] args) {         // 要传的数据start         String data =...
  • liangtll
  • liangtll
  • 2017-01-17 20:50:41
  • 744

RestTemplate 详解

背景这段时间自己做的项目中需要调用服务提供者的服务(接口),具体就是:我这边需要将页面所输入的 Groovy 脚本代码传给别人提供的服务接口,然后那边返回脚本编译的结果给我,我需要将编译结果展示在页面...
  • tzs_1041218129
  • tzs_1041218129
  • 2017-12-03 15:14:57
  • 896
收藏助手
不良信息举报
您举报文章:RestTemplate推送数据无响应的解决办法
举报原因:
原因补充:

(最多只允许输入30个字)