import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.cert.CertificateException;
/***
*https post请求
*lvzhuolin@baidu.com
*/
public class HttpClientUtils {
private static DefaultHttpClient client;
private static void enableSSL(DefaultHttpClient httpclient){
try {
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, new TrustManager[] { truseAllManager }, null);
SSLSocketFactory sf = new SSLSocketFactory(sslcontext);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Scheme https = new Scheme("https", sf, 443);
httpclient.getConnectionManager().getSchemeRegistry().register(https);
} catch (Exception e) {
e.printStackTrace();
}
}
private static TrustManager truseAllManager = new X509TrustManager(){
public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
throws CertificateException {
}
public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
throws CertificateException {
// TODO Auto-generated method stub
}
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
};
/** *//**
* Send a XML-Formed string to HTTP Server by post method
*
* @param url
* the request URL string
* @param xmlData
* XML-Formed string ,will not check whether this string is
* XML-Formed or not
* @return the HTTP response status code ,like 200 represents OK,404 not
* found
* @throws IOException
* @throws ClientProtocolException
*/
public static String sendDataByPost(String url, String data)
throws Exception {
if (client == null) {
// Create HttpClient Object
client = new DefaultHttpClient();
enableSSL(client);
}
client.getParams().setParameter("http.protocol.content-charset", HTTP.UTF_8);
client.getParams().setParameter(HTTP.CONTENT_ENCODING, HTTP.UTF_8);
client.getParams().setParameter(HTTP.CHARSET_PARAM, HTTP.UTF_8);
client.getParams().setParameter(HTTP.DEFAULT_PROTOCOL_CHARSET,
HTTP.UTF_8);
client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10000);
client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 10000);
HttpPost post = new HttpPost(url);
StringEntity entity = new StringEntity(data,"GBK");
entity.setContentType("application/x-www-form-urlencoded");
post.setEntity(entity);
HttpResponse response = client.execute(post);
HttpEntity entityRep = response.getEntity();
String strrep="";
if (entityRep != null) {
strrep = EntityUtils.toString(response.getEntity(),"UTF-8");
// Do not need the rest
post.abort();
}
EntityUtils.consume(entityRep); // instream.close();
return strrep;
}
}
多线程调用sendDataByPost,出现异常:
java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated. Make sure to release the connection before allocating another one.
httpclient 版本是4.5 ,而且代码中包括DefaultHttpClient的很多类都过时了。请问有没有httpclient-4.5以上的解决方案,并且支持多线程调用呢?
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
<p><img height="348" src="https://oscimg.oschina.net/oscnet/up-3ad7667e32c14de3bc3c0d05bd94464bd2c.png" width="712"></p>
你初始化的这块代码,应该放在一个公共的地方,而且只能初始化一次,你这里没有加锁,如果是多线程的话,可能会初始化多次,而且你声明了private static DefaultHttpClient client;它为公共变量,这样,当A线程刚创建成功时,正在执行下面的赋值时,这时B线程又来了,又创建了一个对象,这样A创建的对象有可能会被覆盖掉。
<p>楼主遇到的异常, <span><span>早在 </span>2013/10/11, 就有人 (</span> <a>nice_so</a> <span>) 遇到过。请看看先人的解决案例:</span></p>
httpClient释放链接的问题
也要参看:
调用rest地址时异常:Invalid use of BasicClientConnManager: connection still allocated.
这个方法单次调用没问题,但是多线程调用会报这个错误。在网上查了,EntityUtils.consume(entityRep); 就可以关闭连接。代码中有这个。