【问题标题】:"Illegal State Exception: Already Connected" when using HttpURLConnection使用 HttpURLConnection 时出现“Illegalstateexception:已连接”
【发布时间】:2015-04-27 21:47:14
【问题描述】:

当我将 DoOutput 设置为 true 时,我得到一个非法状态异常。

public boolean sendLinksToMaster(String ipport, List<String> links){

        boolean sent = false;
        String[] tokens = ipport.split(":");    
        String data = edu.cis555.searchengine.utils.Utils.generateLinks(links);
        HttpURLConnection conn=null;
        try{
            String encodedData = URLEncoder.encode(data, "UTF-8");
        try{

                String ip =tokens[0];
                String port = tokens[1];
                String path = edu.cis555.searchengine.utils.Constants.URL_ADD_LINK;
                System.setProperty("http.keepAlive", "false");
                URL u = new URL("http", ip, Integer.parseInt(port),"/"+path);

                conn = (HttpURLConnection)u.openConnection();
                //ERROR IN THIS LINE
                conn.setDoOutput(true);
                conn.setRequestMethod("POST");
                OutputStream stream = conn.getOutputStream();
                stream.write(encodedData.getBytes());
                stream.close();

                if(conn.getResponseCode() == HttpURLConnection.HTTP_OK)
                    sent=true;

            //  LOG.debug(conn.getResponseCode());
                conn.disconnect();
            }catch(MalformedURLException mfe){
                LOG.debug(mfe.getMessage());
                if(conn!=null){
                    conn.disconnect();
                }
            }catch(IOException ioe){
                LOG.debug(ioe.getMessage());
                if(conn!=null){
                    conn.disconnect();
                }
            }

        }catch(Exception e){
            LOG.debug(e.getMessage());
            if(conn!=null){
                conn.disconnect();
            }
        }
        return sent;

    }

显示的堆栈跟踪是:

java.lang.IllegalStateException: Already connected
at java.net.URLConnection.setDoOutput(Unknown Source)
at edu.upenn.cis455.xpathengine.utils.pool.ThreadPool.sendLinksToMaster(ThreadPool.java:357)
at edu.upenn.cis455.xpathengine.utils.pool.ThreadPool$Worker.processAndAddToQueue(ThreadPool.java:314)
at edu.upenn.cis455.xpathengine.utils.pool.ThreadPool$Worker.run(ThreadPool.java:269)
at java.lang.Thread.run(Unknown Source)

我没有发现我在发送请求时做错了什么。谁能指出缺少什么或我做错了什么

【问题讨论】:

  • 基于 HTTPUrlConnection 的源,看起来它希望在连接打开之前调用这些方法(setDoOutputsetRequestMethod),这应该'在您调用 conn.connect() 之前不会发生您的代码在结构上也类似于 URLConnection sample code
  • @Chris 确切地说,我一直在挖掘 URLConnection 源代码以查看发生了什么,并且根本不应该发生错误。
  • 嗯...我自己尝试这个我无法重现您的问题 - 我只是将它简化到足以将其放入独立的主要方法中,将 URL 硬编码为 docs.oracle.com,称为 @987654328 @ 并顺利通过conn.setDoOutput / conn.setRequestMethod(在每一步都验证connected==false)-直到我打电话给conn.getOutputStream()它才被打开
  • 我正在向同一台机器上的 tomcat 上托管的 Web 应用程序发送请求。这会导致问题吗?
  • 只有当您的代码重用打开的HttpURLConnection 而不是每次都创建一个新的(根据您上面的代码)时,您才会遇到该问题。如果您像我一样将其简化为独立的主要方法,您是否能够重现您的问题?如果不是,那么您在此处运行的内容与该独立类之间显然存在一些差异,这应该有助于您调试它。

标签: java httpurlconnection


【解决方案1】:

我遇到了同样的问题并解决了。就我而言,这是因为我在 NetBeans 的调试界面中忘记了 connection.getResponseCode() 的手表。希望它可以帮助其他人犯同样的错误。

如果你有任何与请求的响应值相关的watch,例如getResponseCode()getResponseMessage()getInputStream()甚至只是connect(),在调试模式下会出现这个错误。

之前的所有方法都隐式调用connect() 并触发请求。因此,当您到达setDoOutput 时,连接已经建立。

【讨论】:

  • 哇!我遇到了同样的问题,果然我在调试窗口中有一个 conn.getResponseCode() 的表达式......我删除了它并开始工作。不知道为什么你投了反对票,但我只是投了赞成票
  • 谢谢。我确信这会对其他人有所帮助,因为调试起来并不明显;)
  • 谢谢。它帮助了我。
  • 你太棒了,先生。在 Eclipse 中,我的手表中的表情完全相同。感谢分享。
  • 难以置信有多少开发人员落入了同一个陷阱 :-)
【解决方案2】:

除了前面评论中提到的手表外,如果连接有问题也可能发生。例如:

在像post.getOutputStream().write(jsonBody.getBytes("UTF-8"));这样写入OutPut Stream之后,我正在设置一个属性:post.setRequestProperty("Ocp-Apim-Subscription-Key", "&lt;&gt;")

就像:

post.getOutputStream().write(jsonBody.getBytes("UTF-8"))
post.setRequestProperty("Ocp-Apim-Subscription-Key", "<>")

在这种情况下,我也得到“已连接”。为了解决这个问题,我做了这样的事情:

post.setRequestProperty("Ocp-Apim-Subscription-Key", "<>")
post.getOutputStream().write(jsonBody.getBytes("UTF-8"))

【讨论】:

    【解决方案3】:

    有时它就像确保您没有使用 http 而不是 https 一样简单。

    【讨论】:

      【解决方案4】:

      把stream.close(); 在finally块中

      【讨论】:

      • 代码执行永远不会到达stream.close()。一旦我调用 setDoOutput 就会引发异常
      • 尝试杀死java进程然后再次测试你的代码
      猜你喜欢
      • 1970-01-01
      • 2018-07-07
      • 2014-11-15
      • 1970-01-01
      • 2013-08-27
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多