httpclient 解决 connection reset 问题
错误如下:
java.net.SocketException: Connection reset
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:118)
at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
atorg.apache.http.impl.io.SessionOutputBufferImpl.streamWrite(SessionOutputBufferImpl.java:124)
atorg.apache.http.impl.io.SessionOutputBufferImpl.flushBuffer(SessionOutputBufferImpl.java:136)
atorg.apache.http.impl.io.SessionOutputBufferImpl.write(SessionOutputBufferImpl.java:167)
at org.apache.http.impl.io.ContentLengthOutputStream.write(ContentLengthOutputStream.java:113)
atorg.apache.http.entity.mime.content.FileBody.writeTo(FileBody.java:121)
atorg.apache.http.entity.mime.AbstractMultipartForm.doWriteTo(AbstractMultipartForm.java:134)
at org.apache.http.entity.mime.AbstractMultipartForm.writeTo(AbstractMultipartForm.java:157)
atorg.apache.http.entity.mime.MultipartFormEntity.writeTo(MultipartFormEntity.java:113)
at org.apache.http.impl.DefaultBHttpClientConnection.sendRequestEntity(DefaultBHttpClientConnection.java:156)
atorg.apache.http.impl.conn.CPoolProxy.sendRequestEntity(CPoolProxy.java:162)
atorg.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:238)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:123)
atorg.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271)
atorg.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
atorg.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
atorg.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
atorg.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
atorg.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
atorg.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
解决方法:
1. 使用TCP短链接无效
httppost.setProtocolVersion(HttpVersion.HTTP_1_0);
httppost.addHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
2.设置超时时间
int timeout = 60;
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setSocketTimeout(timeout * 1000)
.setConnectTimeout(timeout * 1000)
.setConnectionRequestTimeout(timeout * 1000)
.build();
3.使用 CloseableHttpResponse
CloseableHttpResponse response = null;
response = httpClient.execute(httpPost);
HttpEntity httpEntity = response.getEntity();
EntityUtils.consume(httpEntity); //按照官方文档的说法:二者都释放了才可以正常的释放链接
response.close();
具体代码如下:
package com.curiousby.cn.srpignbootdemo.util;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
public class HttpHelper {
private final static Logger logger = Logger.getLogger(HttpHelper.class);
public static final String CHARSET = "UTF-8";
private static CloseableHttpClient httpClient = createSSLInsecureClient();
public static final Integer HTTP_OK = 200;
public static final String CONTENT_TYPE_NAME = "Content-Type";
public static final String CONTENT_TYPE_JSON = "application/json;charset=UTF-8";
public static final String CONTENT_TYPE_XML = "text/xml;charset=UTF-8";
public static final String CONTENT_TYPE_FORM = "application/x-www-form-urlencoded;charset=UTF-8";
public static final String ACCEPT_NAME = "Accept";
public static final String ACCEPT = "application/json;charset=UTF-8";
public static final int TIMEOUT = 60;//这个要弄长点
public static String postUrl(String url, Map<String, Object> params) {
String result = null;
CloseableHttpResponse response = null; //返回结果,释放链接
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
try {
if (params != null && !params.isEmpty()) {
for (Map.Entry<String, Object> entry : params.entrySet()) {
String value = Validator.get_obj_or_empty(entry.getValue()).toString();
if (value != null) {
pairs.add(new BasicNameValuePair(entry.getKey(), value));
}
}
}
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setSocketTimeout(TIMEOUT * 1000)
.setConnectTimeout(TIMEOUT * 1000)
.setConnectionRequestTimeout(TIMEOUT * 1000)
.build();
HttpPost httpPost = new HttpPost(url);
httpPost.setProtocolVersion(HttpVersion.HTTP_1_0);
httpPost.addHeader(CONTENT_TYPE_NAME, CONTENT_TYPE_FORM);
httpPost.addHeader(ACCEPT_NAME, ACCEPT);
httpPost.addHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
httpPost.setConfig(defaultRequestConfig);
httpPost.setEntity(new UrlEncodedFormEntity(pairs, CHARSET));
response = httpClient.execute(httpPost); //建立链接得到返回结果
int statusCode = response.getStatusLine().getStatusCode(); //返回的结果码
if (statusCode != 200) {
httpPost.abort();
logger.error("===httphelper==httpclient===请求异常");
return null;
}
HttpEntity httpEntity = response.getEntity();
if (httpEntity == null) {
logger.error("===httphelper==httpclient===返回结果异常");
return null;
} else {
result = EntityUtils.toString(httpEntity, CHARSET);
}
EntityUtils.consume(httpEntity); //按照官方文档的说法:二者都释放了才可以正常的释放链接
response.close();
return result;
} catch (Exception e) {
logger.error("===httphelper==httpclient===请求错误"+e.getMessage()+",错误信息"+e);
return null;
} finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
logger.error("===httphelper==httpclient===关闭流异常"+e.getMessage()+",错误信息"+e);
}
}
}
}
public static CloseableHttpClient createSSLInsecureClient() {
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null,
new TrustStrategy() {
public boolean isTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
return HttpClients.custom().setMaxConnTotal(100).setMaxConnPerRoute(10)
.setSSLSocketFactory(sslsf).build();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
}
return HttpClients.createDefault();
}
}
捐助开发者
在兴趣的驱动下,写一个
免费
的东西,有欣喜,也还有汗水,希望你喜欢我的作品,同时也能支持一下。 当然,有钱捧个钱场(支持支付宝和微信 以及扣扣群),没钱捧个人场,谢谢各位。
个人主页:
http://knight-black-bob.iteye.com/![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuITY1IGNmZWYjZzNjNWOwgTY2YmM0ADM5QWZwAzNlFDOfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
谢谢您的赞助,我会做的更好!