2

EOFException当我调用 REST API 时,我得到了。我知道它说响应为空。但它不应该。我在 iOS 应用程序中使用相同的 API 没有任何问题。

这是我的代码:

try {
    url = new URL(baseUrl);
}
    // Thrown when URL could not be parsed
    catch (MalformedURLException me) {
        Log.e(TAG, "URL could not be parsed. URL : " + baseUrl, me);
    }
    try {

    //      System.setProperty("http.keepAlive", "false");

    // Set connection properties
    urlConnection = (HttpURLConnection) url.openConnection();
    urlConnection.setRequestMethod(method);
    urlConnection.setConnectTimeout(TIMEOUT * 1000);
    urlConnection.setChunkedStreamingMode(0);
    urlConnection.setRequestProperty("Accept", "*/*");
    urlConnection.setRequestProperty("Content-type", "application/x-www-form-urlencoded");

    //      urlConnection.setRequestProperty("Connection", "close");

    if (method.equals("POST") || method.equals("PUT")) {
        // Set to true when posting data
        urlConnection.setDoOutput(true);

        // Write data to post to connection output stream
        OutputStream out = urlConnection.getOutputStream();
        out.write(postParameters.getBytes("UTF-8"));
        Log.d(TAG, "Data written to output stream.");
    }

    //      urlConnection.connect();

    try {
        // Get response
        in = new BufferedInputStream(urlConnection.getInputStream());
    } catch (IOException e) {
            Log.e(TAG,
                    "Exception in getting connection input stream. Input stream : "
                                + in, e);
    }

    Log.d(TAG, "content length : " + urlConnection.getContentLength());
    Log.d(TAG, "content type : " + urlConnection.getContentType());

    // Read the input stream that has response
    statusCode = urlConnection.getResponseCode();
    Log.d(TAG, "Status code : " + statusCode);

    if (statusCode >= 400) {
        Log.e(TAG, "Error stream : " + urlConnection.getErrorStream().toString());
    }
    // Passing input stream to a function.          
    readStream(in, statusCode);
} catch (ProtocolException pe) {
    Log.e(TAG,
                    "Make sure HTTP method is set before connecting to URL. Line : "
                            + getLineNumber(), pe);
} catch (IllegalStateException ie) {
    Log.e(TAG,
                    "Set connection properties before connecting to URL. Line : "
                            + getLineNumber(), ie);
}
// Thrown when connecting to URL times out
catch (SocketTimeoutException se) {
    Log.e(TAG, "Timeout before connecting to URL : " + baseUrl
                    + ". Line : " + getLineNumber(), se);


} catch (IOException e) {
    Log.e(TAG, "Exception while connecting to URL : " + baseUrl, e);
} finally {
    urlConnection.disconnect();
}

我尝试过以下事情,但没有奏效。论文在代码中被注释掉。:

1) System.setProperty("http.keepAlive", "false");
2) urlConnection.setRequestProperty("Connection", "close");
3)urlConnection.connect();

该语句Log.d(TAG, "Status code : " + statusCode);没有被记录。通常它可以工作。

Logcat 屏幕截图:

在此处输入图像描述

4

4 回答 4

1

显然这是由于 HTTPUrlConnection 中的一个错误(参见StackOverflow 上的这个答案)。我建议您实施重试机制。这是我已经实现的,例如:

/** POST an object on the server using the REST API. */
private int httpPOST(String path, JSONObject json) {
    final static int MAX_RETRIES = 3;
    int numTries = 0;
    int responseCode = 0;
    HttpsURLConnection urlConnection = null;
    final long startTime = System.currentTimeMillis();

    while (numTries < MAX_RETRIES) {

        if (numTries != 0) {
            LOGV(TAG, "Retry n°" + numTries);
        }

        // Create (POST) object on server
        try {
            byte[] bytes = json.toString().getBytes("UTF-8");
            URL url = new URL(path);
            urlConnection = (HttpsURLConnection) url.openConnection();
            urlConnection.setDoOutput(true);
            urlConnection.setFixedLengthStreamingMode(bytes.length);
            urlConnection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
            LOGV(TAG, "HTTP POST " + url.toString());
            OutputStream out = urlConnection.getOutputStream();
            out.write(bytes);
            out.close();
            responseCode = urlConnection.getResponseCode();
            LOGV(TAG, "HTTP POST response code: " + responseCode + " (" + (System.currentTimeMillis() - startTime)
                    + "ms)");
            return responseCode;

        } catch (UnsupportedEncodingException e) {
            LOGV(TAG, "Unsupported encoding exception");
        } catch (MalformedURLException e) {
            LOGV(TAG, "Malformed URL exception");
        } catch (IOException e) {
            LOGV(TAG, "IO exception: " + e.toString());
            // e.printStackTrace();
        } finally {

            if (urlConnection != null)
                urlConnection.disconnect();
        }

        numTries++;
    }

    LOGV(TAG, "Max retries reached. Giving up...");

    return responseCode;

}
于 2013-08-21T19:35:56.587 回答
1

该 EOFException 表明响应格式错误 - 可能在标题后缺少空行。在这种情况下,一些 HTTP 客户端代码更加宽容,对我来说,iOS 可以很好地处理我的服务器响应,但我在 Android 上使用 HttpURLConnection 得到了 EOFException。

我的服务器使用的是 python SimpleHTTPServer,我错误地假设我需要做的就是表明成功如下:

self.send_response(200)

这会发送初始响应标头行、服务器和日期标头,但会使流处于您也可以发送其他标头的状态。HTTP 需要在标头之后添加一个新行以指示它们已完成。当您尝试使用 HttpURLConnection 获取结果正文 InputStream 或响应代码等时,如果这条新行不存在,那么它会抛出 EOFException (这实际上是合理的,考虑一下)。一些 HTTP 客户端确实接受了简短的响应并报告了成功结果代码,这导致我可能不公平地指责 HttpURLConnection。

我改变了我的服务器来做到这一点:

self.send_response(200)
self.send_header("Content-Length", "0")
self.end_headers()

该代码不再有 EOFException 。

注意:Android pre-Froyo (2.2) 上存在一些与保持连接相关的错误 - 请参阅此处的博客文章:http ://android-developers.blogspot.co.uk/2011/09/androids-http-clients .html。尽管许多 StackOverflow 的答案都提到了这一点,但我还没有看到令人信服的证据证明新版本的 Android 存在错误(因此我将其放在多个地方......)

于 2015-01-08T17:06:28.647 回答
1

以下代码可能对您有所帮助

HttpEntity entity = response.getEntity();

// All the work is done for you here :)
String jsonContent = EntityUtils.toString(entity);

// Create a Reader from String
Reader stringReader = new StringReader(jsonContent);

// Pass the string reader to JsonReader constructor
JsonReader reader = new JsonReader(stringReader);
reader.setLenient(true);
readGson(reader);

...
// at the end of method return the JSON response
return jsonContent;
于 2013-12-03T12:00:50.860 回答
0

尝试使用库https://github.com/kodart/Httpzoid做同样的事情

于 2013-07-14T19:33:52.463 回答