HttpClient报错 java.lang.IllegalStateException: Invalid use of BasicClientConnManager

颖辉小居 发布于 2020/04/08 10:15
阅读 929
收藏 0

开源之夏第三届火热来袭,高校学生参与赢万元奖金!>>>

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以上的解决方案,并且支持多线程调用呢?

以下是问题补充:

@颖辉小居:这个方法单次调用没问题,但是多线程调用会报这个错误。在网上查了,EntityUtils.consume(entityRep); 就可以关闭连接。代码中有这个。 (2020/04/09 11:57)
加载中
1
wgslucky
wgslucky

你初始化的这块代码,应该放在一个公共的地方,而且只能初始化一次,你这里没有加锁,如果是多线程的话,可能会初始化多次,而且你声明了private static DefaultHttpClient client;它为公共变量,这样,当A线程刚创建成功时,正在执行下面的赋值时,这时B线程又来了,又创建了一个对象,这样A创建的对象有可能会被覆盖掉。

0
tcxu
tcxu
该评论暂时无法显示,详情咨询 QQ 群:点此入群
颖辉小居
颖辉小居
这个方法单次调用没问题,但是多线程调用会报这个错误。在网上查了,EntityUtils.consume(entityRep); 就可以关闭连接。代码中有这个。
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部