【问题标题】:DataOutputSteam is throwing me a 'java.io.IOException: unexpected end of stream'?DataOutputSteam 给我一个“java.io.IOException:流的意外结束”?
【发布时间】:2014-05-18 13:53:15
【问题描述】:

我正在尝试使用 HttpUrlConnection 从 Android 应用程序向 WebService 发出请求。但有时有效,有时无效。

当我尝试发送这个值时:

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

【问题讨论】:

  • 这可能与您的问题无关:您不想使用 DataOutputStream 实例。这是一种二进制的,相当专有的格式。正确的做法是使用UTF-8编码将JSON字符串转换成字节数组,然后直接写入到连接的输出流中。
  • 代码中的另一个问题是您使用默认编码将 JSON 字符串转换为字节数组。然后,您使用数组的长度来设置内容长度。但是,您应用 DataOutputStream 以将字符串以 ASCII 模式写入(writeBytes 不使用编码;它会丢弃高位)。因此,您可能在宣布的内容长度和有效内容长度之间存在不匹配。

标签: java android httpurlconnection dataoutputstream


【解决方案1】:

这是一个具有以下更改的解决方案:

  • 它摆脱了 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();

    ...
}

【讨论】:

  • 我真的爱你,当字符串包含重音字符(如 'í')时,问题就出现了,但你的方法就像一个魅力。
  • @Laggel:这可能是由于编码问题吗?例如,如果使用 UTF-8 等多字节编码,则重音字符通常会占用超过 1 个字节,然后字节长度与字符数不再匹配。
  • 是的,这就是为什么需要在编码为UTF-8后取长度。
【解决方案2】:

来自 oracle 文档here。我们知道 DataOutputStream 的 flush 方法调用了底层输出流的 flush 方法。如果您查看here 中的 URLConnection 类,它表示 URLConnection 的每个子类都必须重写此方法。如果您看到 HttpUrlConnection here,我们会看到 flush 方法未被覆盖。这可能是您出现问题的原因之一。

【讨论】:

    猜你喜欢
    • 2022-08-24
    • 2019-03-14
    • 1970-01-01
    • 2018-09-01
    • 2020-08-08
    • 2015-11-17
    • 1970-01-01
    • 1970-01-01
    • 2017-05-03
    相关资源
    最近更新 更多