HttpURLConnection Post:输出流没有效果?

时间:2012-04-07 21:23:21

标签: android post httpurlconnection

我正在开发一个Android应用程序,并且已经发现不同的Android版本在处理Http(s)URLConnections(http://stackoverflow.com/q/9556316/151682)方面有不同的方式。

我遇到了Android 4很好地通过HTTPS执行POST请求的问题,在运行下面的代码时会自动添加Content-Type等标题。

但是,在Android 2.3.5(设备和模拟器)上,对输出流的任何写入似乎都被忽略 - 我使用Web代理Charles调试它,并且在发送所有标头时,将数据写入输出流没有被发送......

任何人都知道如何解决这个问题?

注意:由于我正在开发的API只有一个自签名证书,我现在需要禁用认证验证。

TIA,Patrick

更新 与此同时,我也试图效仿,但无济于事:

  • 在BufferedOutputStream上close()调用后调用flush()
  • 在OutputStream和BufferedOutputStream上调用close()
  • 使用OutputStreamWriter代替
  • 在致电close()

    之前未调用getInputStream()
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setConnectTimeout(CONNECT_TIMEOUT);
    
    connection.setDoOutput(true); // Triggers POST.
    connection.setRequestMethod("POST");
    int contentLength = 0;
    if(body != null) {
        contentLength = body.getBytes().length;
    }
    
    // Workarounds for older Android versions who do not do that automatically (2.3.5 for example)
    connection.setRequestProperty(HTTP.TARGET_HOST, url.getHost());
    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    
    // Set SSL Context -- Development only
    if(context != null && connection instanceof HttpsURLConnection){
        HttpsURLConnection conn = (HttpsURLConnection)connection;
        conn.setSSLSocketFactory(context.getSocketFactory());
        conn.setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });
    }
    
    try{
        // Add headers
        if(headers != null){
            for (NameValuePair nvp : headers) {
                if(nvp != null){
                    connection.setRequestProperty(nvp.getName(), nvp.getValue());
                }
            }
        }
    
        connection.setFixedLengthStreamingMode(contentLength);
        OutputStream outputStream = null;
        try {
            if(body != null){
                outputStream = connection.getOutputStream();
                BufferedOutputStream stream = new BufferedOutputStream(outputStream);
                stream.write(body.getBytes()); // <<<< No effect ?!
                stream.flush();
    
            }
        } finally {
            if (outputStream != null) 
                try { 
                    outputStream.close(); 
                }
            catch (IOException logOrIgnore) {
                // ...
            }
        }
    
        InputStream inputStream = connection.getInputStream();
    
        // .... Normal case ....
    
    }
    catch(IOException e){
        // ... Exception! Check Error stream and the response code ...
    
    
    }
    finally{
        connection.disconnect();
    }
    

    }

2 个答案:

答案 0 :(得分:6)

对我而言,您调用DoSetOutput等的顺序似乎是奇怪行为的原因......

一些链接/来源与Android上的HTTP POST工作代码:

答案 1 :(得分:4)

啊,我终于找到了。寻找错误的地方......问题是标题:

我上面的代码实际上工作正常 - 原因是我包含了一个Base64编码的头。在我的Android 2.3.5上,指定的选项(Base64.DEFAULT)似乎在末尾插入了一个额外的换行符,它过早地结束了请求,让我没有时间发送实际的正文。 在Android 4上,默认似乎更改为BASE64.NO_WRAP,如下面链接的帖子中所述......

实际上已经回答了here

感谢您的努力。

相关问题