2014-05-18 62 views
11

我正在嘗試使用HttpUrlConnection從Android應用程序向WebService發出請求。但有時它有效,有時卻不行。DataOutputSteam拋出一個'java.io.IOException:意外的流結束'?

當我嘗試發送此值:

JSON值

{"Calle":"Calle Pérez 105","DetalleDireccion":"","HoraPartida":"May 18, 2014 9:17:10 AM","Numero":0,"PuntoPartidaLat":18.477295994621315,"PuntoPartidaLon":-69.93638522922993,"Sector":"Main Sector"} 

我得到了一個「流意外結束」中的異常DataOutputStream類關閉功能。

這裏是我的代碼:

DataOutputStream printout; 
// String json; 
byte[] bytes; 
DataInputStream input; 

URL serverUrl = null; 
try { 
    serverUrl = new URL(Config.APP_SERVER_URL + URL); 
} catch (MalformedURLException e) { 
    ... 
} 

bytes = json.getBytes(); 
try { 

    httpCon = (HttpURLConnection) serverUrl.openConnection(); 
    httpCon.setDoOutput(true); 
    httpCon.setUseCaches(false); 
    httpCon.setFixedLengthStreamingMode(bytes.length); 
    httpCon.setRequestProperty("Authorization", tokenType + " "+ accessToken); 
    httpCon.setRequestMethod("POST"); 
    httpCon.setRequestProperty("Content-Type", "application/json"); 

    printout = new DataOutputStream(httpCon.getOutputStream()); 
    printout.writeBytes(json); 
    printout.flush(); 
    printout.close(); 
    ... 
} 
+0

它可能不涉及到你的問題:你不想使用* DataOutputStream類*實例。這是一種二進制,而非專有格式。正確的方法是使用UTF-8編碼將JSON字符串轉換爲字節數組,然後將其直接寫入連接的輸出流。 – Codo

+0

您代碼中的另一個問題是您使用默認編碼將JSON字符串轉換爲字節數組。然後使用數組的長度來設置內容長度。但是,應用* DataOutputStream *的方式是以ASCII模式寫入字符串(writeBytes不使用編碼;它丟棄高位)。所以你可能在宣佈的和有效的內容長度之間不匹配。 – Codo

回答

7

這裏的有以下變化的解決方案:

  • 它擺脫了DataOutputStream類,這肯定是使用了錯誤的事情。
  • 它正確設置和傳遞內容長度。
  • 它不依賴於關於編碼的任何默認值,但明確地在兩個地方設置UTF-8。

試試:

// String json; 

URL serverUrl = null; 
try { 
    serverUrl = new URL(Config.APP_SERVER_URL + URL); 
} catch (MalformedURLException e) { 
    ... 
} 

try { 
    byte[] bytes = json.getBytes("UTF-8"); 

    httpCon = (HttpURLConnection) serverUrl.openConnection(); 
    httpCon.setDoOutput(true); 
    httpCon.setUseCaches(false); 
    httpCon.setFixedLengthStreamingMode(bytes.length); 
    httpCon.setRequestProperty("Authorization", tokenType + " "+ accessToken); 
    httpCon.setRequestMethod("POST"); 
    httpCon.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); 

    OutputStream os = httpCon.getOutputStream(); 
    os.write(bytes); 
    os.close(); 

    ... 
} 
+0

我真的愛你,當字符串包含像'í'這樣的重音字符時,問題就發生了,但是你的方法像魅力一樣工作。 – Laggel

+1

@Laggel:這可能是由於編碼問題?例如,如果使用諸如UTF-8的多字節編碼,則重音字符通常會佔用多於1個字節,然後字節長度與字符數量不再匹配。 –

+1

是的,這就是爲什麼在將其編碼爲UTF-8之後需要使用長度的原因。 – Codo

1

從Oracle文檔here。我們知道DataOutputStream的flush方法調用底層輸出流的flush方法。如果您查看here中的URLConnection類,則說明URLConnection的每個子類都必須覆蓋此方法。如果您看到HttpUrlConnection here,我們會看到flush方法未被覆蓋。這可能是你的問題的原因之一。