开发者社区 问答 正文

HttpClient报错 java.lang.IllegalStateExcep?400报错

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

展开
收起
爱吃鱼的程序员 2020-06-05 14:05:46 907 分享 版权
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB
                        <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); 就可以关闭连接。代码中有这个。
    
    2020-06-05 14:06:06
    赞同 展开评论
问答分类:
问答标签:
问答地址: