2014-05-18 24 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方法未被覆盖。这可能是你的问题的原因之一。