java中http请求之restTemplate配置超时时间(亲测有用!)

问题:http请求发起后接收不到返回数据!!!【测试环境没出问题,发到正式环境就有问题】

项目中通过restTemplate发起请求:

        log.info("请求入参:{}",JSON.toJSONString(request));//打印日志1// 配置http请求的连接超时时间和读取超时时间HttpsClientRequestFactory factory = new HttpsClientRequestFactory();factory.setConnectTimeout(60 * 1000);factory.setReadTimeout(5 * 60 * 1000);RestTemplate restTemplate = new RestTemplate(factory);Result result = restTemplate.postForObject(address.concat(inventoryUrl), request, Result.class);log.info("库存同步,返回数据: {}", result);//打印日志2

打印日志1内容为:

http请求入参:{data=[{ productStatus=10,skuCode=null}], messageId=ewpfpr1t6ey5r6qj0su0w1h6rt73hr,token=vgvU5EJKuZbuHii7WH6pTINp40ZRicaqLz4dq5P7L6pDzWir8EEGZhCKPucQjljsw69EHasEy+iJfdTofDg==}

日志打印2没有打印内容!!!

最后发现是因为测试环境中数据量较小,http请求后,很快能得到相应,而正式环境数据量较大,没有及时得到响应,连接或者读取超时!!!

三种解决方式:

第一种

1、添加HttpsClientRequestFactory 类,并继承SimpleClientHttpRequestFactory 

/*** 兼容调Https接口*/
public class HttpsClientRequestFactory extends SimpleClientHttpRequestFactory {@Overrideprotected void prepareConnection(HttpURLConnection connection, String httpMethod)throws IOException {if (connection instanceof HttpsURLConnection) {prepareHttpsConnection((HttpsURLConnection) connection);}super.prepareConnection(connection, httpMethod);}private void prepareHttpsConnection(HttpsURLConnection connection) {connection.setHostnameVerifier(new SkipHostnameVerifier());try {connection.setSSLSocketFactory(createSslSocketFactory());}catch (Exception ex) {// Ignore}}private SSLSocketFactory createSslSocketFactory() throws Exception {SSLContext context = SSLContext.getInstance("TLS");context.init(null, new TrustManager[] { new SkipX509TrustManager() },new SecureRandom());return context.getSocketFactory();}private class SkipHostnameVerifier implements HostnameVerifier {@Overridepublic boolean verify(String s, SSLSession sslSession) {return true;}}private static class SkipX509TrustManager implements X509TrustManager {@Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}@Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) {}@Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) {}}
}

2、使用restTemplate发起请求前先设置连接和超时时间即可;

//配置http请求的连接超时时间和读取超时时间
HttpsClientRequestFactory factory = new HttpsClientRequestFactory();
factory.setConnectTimeout(60 * 1000);
factory.setReadTimeout(5 * 60 * 1000);
RestTemplate restTemplate = new RestTemplate(factory);
BaseResult result = restTemplate.postForObject(address.concat(inventoryUrl), request, Result.class);

或者通过容器加载配置类,然后设置超时时间进去,使用的时候直接注入restTemplate即可!;

@Configuration
public class RestConfig {//60 * 1000@Value("${rest.connectTimeout:60000}")private int connectTimeout;//5 * 60 * 1000@Value("${rest.readTimeout:300000}")private int readTimeout;@Beanpublic RestTemplate restTemplate() {SimpleClientHttpRequestFactory simpleClientHttpRequestFactory = new SimpleClientHttpRequestFactory();simpleClientHttpRequestFactory.setConnectTimeout(connectTimeout);simpleClientHttpRequestFactory.setReadTimeout(readTimeout);RestTemplate restTemplate = new RestTemplate(simpleClientHttpRequestFactory);return restTemplate;}

第二种

@Configuration
public class RestConfig {//60 * 1000@Value("${rest.connectTimeout:60000}")private int connectTimeout;//5 * 60 * 1000@Value("${rest.readTimeout:300000}")private int readTimeout;  @Value("${rest.connectionRequestTimeout:300000}")private int connectionRequestTimeout;  /*** 使用 HttpComponentsClientHttpRequestFactory创建http请求(推荐)*/@Beanpublic RestTemplate restTemplate() {HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();httpRequestFactory.setConnectionRequestTimeout(connectionRequestTimeout);httpRequestFactory.setConnectTimeout(connectTimeout);httpRequestFactory.setReadTimeout(readTimeout);return new RestTemplate(httpRequestFactory);}
}

第三种(基于第二种升级)

@Configuration
public class RestConfig {/*** 高并发采用HttpClient连接池*/@Beanpublic RestTemplate restTemplate() {return new RestTemplate(httpRequestFactory());}@Beanpublic ClientHttpRequestFactory httpRequestFactory() {return new HttpComponentsClientHttpRequestFactory(httpClient());}@Beanpublic HttpClient httpClient() {Registry registry = RegistryBuilder.create().register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https", SSLConnectionSocketFactory.getSocketFactory()).build();PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);//设置整个连接池最大连接数connectionManager.setMaxTotal(400);//路由是对maxTotal的细分connectionManager.setDefaultMaxPerRoute(100);RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(30000)  //返回数据的超时时间.setConnectTimeout(20000) //连接上服务器的超时时间.setConnectionRequestTimeout(1000) //从连接池中获取连接的超时时间.build();return HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).setConnectionManager(connectionManager).build();}
}

问题得到解决、、、、、、


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部