【问题标题】:URL.openConnection() connects immediatelyURL.openConnection() 立即连接
【发布时间】:2016-11-10 18:42:27
【问题描述】:

由于 Android 从他们的 SDK 中删除了自 6.0 以来的 apache Web 客户端,并且我不希望在我的 apk 中包含该库,因此我正在迁移到 HttpURLConnection 方法。

为了进行测试,我在本地服务器上创建了一个 testPost.php,它只向我的数据库添加一个日志条目,大致如下:

<?php
  require_once(__DIR__ . '/db_interface.php');
  $conn = connectToDatabase();
  $stmt = $conn->prepare('insert into logs(data) values (?)');
  $stmt->bind_param(1, $_POST['data']);
  $stmt->execute();
  $stmt->close();

当我使用旧的 Web 客户端访问它时,它工作得很好。我的 PC 的网络浏览器也是如此。

现在,当我尝试这个 android 代码时:

        HttpURLConnection connection = null;
        try {
            URL url = new URL("http://192.168.2.221/testPost.php");

            connection = (HttpURLConnection) url.openConnection();
            //As soon as the debugger steps over the above line, the
            //PHP script executes.

            //Line below throws IllegalStateException: Already Connected
            connection.setDoOutput(true); 

            ... 
        } finally {
            if ( connection != null ) connection.disconnect();
        }

我一打开连接就收到异常,就好像它连接一样。 调试后,我注意到当我越过url.openConnection() 时,脚本就会执行并将日志条目保存到数据库中(带有一个空字符串)。

应该将数据 POST 到我的服务器的完整 android 代码:

        HttpURLConnection connection = null;
        try {
            URL url = new URL("http://192.168.2.221/testPost.php");

            connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true); //throws IllegalStateException: Already Connected


            if ( timeout > 0 ) {
                connection.setReadTimeout(timeout * 1000);
                connection.setConnectTimeout(timeout * 1000);
            }

            String postString = writePostParams(params);
            byte[] postData = postString.getBytes("UTF-8");
            connection.setFixedLengthStreamingMode(postData.length);

            OutputStream out = new BufferedOutputStream(connection.getOutputStream());
            out.write(postData);
            out.flush();
            out.close();

            InputStream in = new BufferedInputStream(connection.getInputStream());
            String response = Util.readInputStream(in);

        } catch ( Exception ex ) {
            Debug.log(ex);
        } finally {
            if ( connection != null ) connection.disconnect();
        }

我正在运行 android 6.0.1 的三星 Galaxy S7 上进行测试

添加:也在运行 Android 5.0.2 的模拟器上进行了尝试,结果相同。

异常堆栈跟踪:

07-08 10:39:30.141 23498-23875/? W/System.err: java.lang.IllegalStateException: Already connected
07-08 10:39:30.141 23498-23875/? W/System.err:     at java.net.URLConnection.checkNotConnected(URLConnection.java:463)
07-08 10:39:30.141 23498-23875/? W/System.err:     at java.net.URLConnection.setDoOutput(URLConnection.java:877)
07-08 10:39:30.141 23498-23875/? W/System.err:     at com.package.from.my.app.executeURL(Server.java:1195)  (the line where setDoOutput() is)

已解决
这可能会进入我所做的愚蠢事情的个人名人堂。 我的调试器有一个手表设置为connection.getResponseMessage(),当我越过openConnection() 行时,它就会被评估,从而打开和关闭我的连接。

感谢您的努力,希望这可以为其他人节省一个小时的调试时间。

【问题讨论】:

  • 你能发布异常日志吗
  • @VivekMishra 添加了。
  • stackoverflow.com/questions/2793150/…。检查此链接以正确实施开放连接。同样doInput 隐式将请求类型设置为发布,如果您不需要它,您可以删除该行
  • 我不使用doInput,我很确定您的意思是setDoOutput(如果我没记错的话,就是将请求设置为POST)。此外,将我的代码与该问题中接受的答案(POST 请求的代码)进行比较,结果几乎相同(url.openConnection 后跟setDoOutput)。我将在运行早期版本 android 的模拟器上进行测试,看看它是否可能是此设备上的错误。
  • 当我阅读您的解决方案时,我想,“哇,谁会这样做?”然后我意识到我做了完全相同的事情。你解决了我的问题,而且你并不孤单!

标签: android httpurlconnection


【解决方案1】:

实际上,您的代码看起来不错,即使在文档中它们实现的方式与您在下面的链接中搜索“发布内容”的方式相同,但唯一缺少的是您希望如何发送数据。他们正在使用块 urlConnection.setChunkedStreamingMode(0);
https://developer.android.com/reference/java/net/HttpURLConnection.html 让我用我的服务器测试他们的方法并检查我是否得到相同的精确度。

我测试了这段代码它工作正常我没有得到那个异常

public void testURL() {

        HttpURLConnection urlConnection = null;
        try {
            URL url = new URL("http://www.android.com/");
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setDoOutput(true);
            urlConnection.setChunkedStreamingMode(0);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            urlConnection.disconnect();
        }
    }

这可能是一些服务器安全问题。

【讨论】:

  • 有趣,我也尝试将我的数据发布到https://posttestserver.com/post.php,同样的例外。我可以尝试使用分块流模式,但我看不出有任何区别,因为在抛出异常之前我的代码甚至没有到达该行。
  • 我会尝试在不同的模拟器实例上运行它让我们看看。你可以把设备规格发给我。
猜你喜欢
  • 2012-12-16
  • 2016-02-23
  • 1970-01-01
  • 2020-02-07
  • 2017-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-30
相关资源
最近更新 更多