2013-06-20 3 views
2

REST API를 호출 할 때 EOFException이 표시됩니다. 나는 응답이 null이라는 것을 알고있다. 하지만 그렇게해서는 안됩니다. iOS 응용 프로그램에서 동일한 API를 아무런 문제없이 사용합니다. 내가 일을 다음과 같은 시도했지만 작동하지 않았다HttpUrlConnection을 사용하여 java.io.EOFException 가져 오기

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(); 
} 

:

여기 내 코드입니다. 논문에서 주석을 주석 처리합니다. : 문 Log.d(TAG, "Status code : " + statusCode);가 기록 점점되지 urlConnection.connect();



1) System.setProperty("http.keepAlive", "false");
2) urlConnection.setRequestProperty("Connection", "close");
3). 일반적으로 작동합니다.

로그 캣의 스크린 샷 :

enter image description here

답변

1

은 분명히이 (this answer on StackOverflow 참조) HttpURLConnection의 버그로 인해 라이브러리를 사용하여 확인합니다. 재시도 메커니즘을 구현하는 것이 좋습니다. 이것은 내가 예를 들어 구현 한 것입니다 :

/** 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

다음 코드는 응답이 잘못되었습니다 EOFException는 알 당신에게

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

도움이 될 수 있습니다 - 아마도 헤더 다음에 빈 줄을 부족. 어떤 경우에는 HTTP 클라이언트 코드가 더 용서가된다. iOS가 내 서버 응답을 잘 처리 할 수 ​​있지만 HttpURLConnection을 사용하여 Android에서 EOFException을 받고있다.

내 서버가 파이썬 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는 :

내가 대신이 일을 내 서버를 변경했습니다.

NB : Keep-Alive 연결과 관련된 Android pre-Froyo (2.2)에는 몇 가지 버그가 있습니다. 블로그 게시물 (http://android-developers.blogspot.co.uk/2011/09/androids-http-clients.html)을 참조하십시오. 나는 많은 안드로이드의 새로운 버전의 버그에 대한 설득력있는 증거를 아직 보지 못했다. 그러나 많은 StackOverflow 응답은 그것을 언급하고있다.)

관련 문제