2013-06-20 16 views
2

我得到EOFException当我所说的REST API。我知道它说响应为空。但它不应该。我在iOS应用程序中使用相同的API没有任何问题。获取java.io.EOFException的使用HttpURLConnection的

这里是我的代码:

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的屏幕截图:

enter image description here

回答

1

显然,这是由于在HttpURLConnection的一个bug(见this answer on 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; 

} 
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; 
1

这EOFException类建议的响应格式不正确 - 或许缺少头后,一个空行。一些HTTP客户端代码是在这种情况下更多的宽容,对我的iOS可以处理我的服务器响应很好,但我使用HttpURLConnection的Android变得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的错误的令人信服的证据(因此,为什么我将它置于多个位置......)

相关问题