问题: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<InventoryResult> 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 {
@Override
protected 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 {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
}
private static class SkipX509TrustManager implements X509TrustManager {
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@Override
public 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<QueryInventoryResult> 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;
@Bean
public 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请求(推荐)
*/
@Bean
public RestTemplate restTemplate() {
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectionRequestTimeout(connectionRequestTimeout);
httpRequestFactory.setConnectTimeout(connectTimeout);
httpRequestFactory.setReadTimeout(readTimeout);
return new RestTemplate(httpRequestFactory);
}
}
第三种(基于第二种升级)文章来源:https://www.toymoban.com/news/detail-502313.html
@Configuration
public class RestConfig {
/**
* 高并发采用HttpClient连接池
*/
@Bean
public RestTemplate restTemplate() {
return new RestTemplate(httpRequestFactory());
}
@Bean
public ClientHttpRequestFactory httpRequestFactory() {
return new HttpComponentsClientHttpRequestFactory(httpClient());
}
@Bean
public HttpClient httpClient() {
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>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();
}
}
问题得到解决、、、、、、文章来源地址https://www.toymoban.com/news/detail-502313.html
到了这里,关于java中http请求之restTemplate配置超时时间(亲测有用!)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!