httpClient释放链接的问题
昨天接触到了httpclient和jsoup,
使用httpclient模拟登陆OA,想抓OA的数据下来,无实在意义,只是练手。
不过在过程中出了一点问题。
public static boolean login(){ HttpGet get = new HttpGet(uri+"/logincheck.php"); List<NameValuePair> params = new ArrayList<NameValuePair>(); //.... try { String str = EntityUtils.toString(new UrlEncodedFormEntity(params)); get.setURI(new URI(get.getURI()+"?"+str)); response = client.execute(get); //.... } catch (Exception e) { e.printStackTrace(); } if(response.getStatusLine().getStatusCode()==200){ System.out.println("登陆成功!"); return true; }else{ return false; } }这个方法没有问题,不过在登陆之后,我直接访问一个OA里面的新闻页面,去抓数据的时候就会出错。
public static String getNewsContent(){ HttpGet get = new HttpGet(uri+"/general/notify/show"); try { response = client.execute(get); HttpEntity entity = response.getEntity(); String newsContent = EntityUtils.toString(entity); Document doc = Jsoup.parse(newsContent); Elements elements = doc.getElementsByClass("TableLine1"); for(Element element : elements){ System.out.println(element.val()); } } catch (Exception e) { e.printStackTrace(); } return ""; }在第二次client.execute(get)的时候就会报错。
java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated. Make sure to release the connection before allocating another one.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(17)
http请求都是分开请求的,但是两个http请求可以共用一个Socket连接
你需要的解决的是,怎么在第二次请求的时候,带上第一次请求返回的sessionid
请求结束后调用get.abort或者EntityUtils.consume试试
我的意思是在 第一次请求结束后,怎么保持登录状态进行第二次请求。 释放连接,第二次请求的时候又没登录, 不释放连接,就又报上面的错误。 就像用户登录了之后进行操作一样。
感谢答主,碰到同样的问题,我这边关闭response就行了
那怎么让程序记住自己的登录状态,继而去请求下一个需要登录才能请求的页面呢
回复
两个请求就得用两个连接,如何连接的是httpclient封装在内部的,外部不做此控制,就像你用普通jsp请求一样,你面向的是一次次的请求,而不是连接,而且每次请求必须释放,不然端口一直占用着
我的意思是在 第一次请求结束后,怎么保持登录状态进行第二次请求。 释放连接,第二次请求的时候又没登录, 不释放连接,就又报上面的错误。 就像用户登录了之后进行操作一样。
提示很明确,你没有释放连接,我在官方的Samples里面找到一段代码应该可以帮助你
我的意思是在 第一次请求结束后,怎么保持登录状态进行第二次请求。 释放连接,第二次请求的时候又没登录, 不释放连接,就又报上面的错误。 就像用户登录了之后进行操作一样。
回复
consume又不是释放连接,销毁你打开的entity而已,你的client还是那个就行
不知道你用的哪个版本,4.x之后改动挺多的,和你这个问题相关的比如PoolingClientConnectionManager代替了ThreadSafeClientConnManager、EntityUtils.consume代替了consumeContent
,用连接池维护或者每次打开entity之后consume
我的意思是在 第一次请求结束后,怎么保持登录状态进行第二次请求。 就像用户登录了之后进行操作一样。
回复
用发登录请求的HttpClient对象再次请求就行啊
不行的,会报错,就是上面的那个错误。 可以看我上面的代码,就是你说的那样
请求结束后调用get.abort或者EntityUtils.consume试试
请求结束后调用get.abort或者EntityUtils.consume试试
引用来自“lietome”的答案
提示很明确,你没有释放连接,我在官方的Samples里面找到一段代码应该可以帮助你