DataOutputSteam бросает мне "java.io.IOException: неожиданный конец потока"?

Я пытаюсь сделать запрос к WebService из приложения Android, используя HttpUrlConnection. Но иногда это работает, а иногда и нет.

Когда я попытаюсь отправить это значение:

Значение 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();
    ...
}

Ответ 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();

    ...
}

Ответ 2

Из документации оракула здесь. Мы знаем, что метод flush метода DataOutputStream вызывает метод flush базового выходного потока. Если вы посмотрите на класс URLConnection в здесь, он говорит, что каждый подкласс URLConnection должен иметь этот метод переопределенным. Если вы видите HttpUrlConnection здесь, мы видим, что метод flush не переопределяется. Это может быть одной из причин вашей проблемы.