Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/202.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android HttpURLConnection getResponseCode未返回_Android_Httpurlconnection - Fatal编程技术网

Android HttpURLConnection getResponseCode未返回

Android HttpURLConnection getResponseCode未返回,android,httpurlconnection,Android,Httpurlconnection,我试图在Android上使用HttpURLConnection将一个文件发布到我们的服务器,但是getResponseCode调用只是挂起,永远不会返回。这个问题源于文件对于服务器来说太大,所以服务器返回了一个HTTP错误代码413(我可以在服务器日志中看到),但是在我们的设备上,似乎从来没有收到过。我在我们的应用程序中有以下代码: public FileUploadUtility(URL requestURL, File uploadFile) throws IOException {

我试图在Android上使用HttpURLConnection将一个文件发布到我们的服务器,但是getResponseCode调用只是挂起,永远不会返回。这个问题源于文件对于服务器来说太大,所以服务器返回了一个HTTP错误代码413(我可以在服务器日志中看到),但是在我们的设备上,似乎从来没有收到过。我在我们的应用程序中有以下代码:

public FileUploadUtility(URL requestURL, File uploadFile) throws IOException
{
    file = uploadFile;
    String fileName = uploadFile.getName();

    httpURLConnection = (HttpURLConnection) requestURL.openConnection();
    httpURLConnection.setUseCaches(false);
    httpURLConnection.setDoOutput(true);
    httpURLConnection.setDoInput(true);
    httpURLConnection.setRequestMethod("POST");
    httpURLConnection.setRequestProperty("Content-Type", URLConnection.guessContentTypeFromName(fileName));
    //httpURLConnection.setRequestProperty("Content-Length", Long.toString(fileSize));
    long fileSize = uploadFile.length();
    httpURLConnection.setFixedLengthStreamingMode(fileSize);
    outputStream = httpURLConnection.getOutputStream();
}

/**
 * Completes the request and receives response from the server.
 *
 * @return a list of Strings as response in case the server returned
 * status OK, otherwise an exception is thrown.
 * @throws IOException
 */
public String finish(ProgressListener progressListener) throws IOException, HTTPErrorCodeException
{
    try (FileInputStream inputStream = new FileInputStream(file))
    {
        byte[] buffer = new byte[100 * 1024];
        int bytesRead;

        long fileSize = file.length();
        int total = 0;
        while ((bytesRead = inputStream.read(buffer)) != -1)
        {
            outputStream.write(buffer, 0, bytesRead);

            total += bytesRead;
            if(fileSize > 0)
            {
                progressListener.fileUploadProgress((float)total / (float)fileSize);
            }
        }
        outputStream.flush();
    }
    catch (Exception e)
    {
        e.printStackTrace();
        throw new IOException("Error uploading file: " + e.getMessage());
    }

    String response;

    // Checks server's status code first
    int status = httpURLConnection.getResponseCode();
    if (status == HttpURLConnection.HTTP_OK)
    {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream())))
        {
            StringBuilder builder = new StringBuilder();
            String output;
            while ((output = reader.readLine()) != null)
            {
                builder.append(output);
            }
            response = builder.toString();
            Log.i("Server response body", response);
        }
        httpURLConnection.disconnect();
        httpURLConnection = null;
    }
    else
    {

        String serverResponseMessage = httpURLConnection.getResponseMessage();
        Log.i("Server Response Message", serverResponseMessage);

        try (BufferedReader responseReader = new BufferedReader(new InputStreamReader((httpURLConnection.getInputStream()))))
        {
            StringBuilder builder = new StringBuilder();
            String output;
            while ((output = responseReader.readLine()) != null)
            {
                builder.append(output);
            }
            Log.i("Server response body", builder.toString());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        try (BufferedReader errorReader = new BufferedReader(new InputStreamReader((httpURLConnection.getErrorStream()))))
        {
            StringBuilder builder = new StringBuilder();
            String output;
            while ((output = errorReader.readLine()) != null)
            {
                builder.append(output);
            }
            Log.i("Server error", builder.toString());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        throw new HTTPErrorCodeException(status);
    }

    return response;
}
只是重申一下,问题不在于“为什么服务器拒绝上传”,而是为什么HttpURLConnection似乎没有接收到响应代码。当闯入调试器时,HttpURLConnection似乎在尝试写入输出缓冲区时被卡住,但服务器在应用程序完成写入输出缓冲区之前已经发送了响应代码(因为服务器已根据标头拒绝POST)。服务器是Nginx转发到Node.JS实例,如果这有帮助的话,但正如我在日志中看到的413,我认为这是应用程序方面的问题。它挂在以下行上:

int status = httpURLConnection.getResponseCode();

因此,问题在于HttpURLConnection关闭,希望在读取任何响应之前上传整个主体。Nginx正在发送413响应并在应用程序发送正文之前关闭连接,但HttpURLConnection仍在尝试发送正文。由于连接在Nginx端关闭,发送数据失败,但HttpURLConnection没有指定默认超时。理想情况下,HttpURLConnection会在尝试编写输出时检查早期响应头,在以后的Android版本中可能会这样做(我正在测试4.4,所以我不确定这在以后的版本中是否更有效)。目前,设置超时似乎有效:

httpURLConnection.setConnectTimeout(10 * 1000);
httpURLConnection.setReadTimeout(10 * 1000);

不,不是。服务器在读取请求之前不会发送响应。任何相反的期望都是错误的。与
HttpURLConnection
无关。服务器在发送整个正文之前发送响应-即,在发送请求的整个正文之前,它从请求中读取标头,确定正文过大并发送响应。看@EJP你有没有看过那个链接?就我所知,我的答案是正确的,但如果答案不正确,最好能得到更好的解释。