简体   繁体   中英

BufferedReader.readLine(): How to avoid exception when empty data?

After making a connection with HttpsURLConnection I read the input buffer. Everything works fine except that if the data returned is empty (just a 200 with 0 bytes) reader.readLine() raises an IOException. (EDIT: it is in fact a timeout)

What IF statement can I write before reader.readLine() so I can catch this in advance?

NOTE: a tricky part might be that we still need to wait for the buffer to have received everything, so the IF needs to be "We received everything, but there is nothing."

Thanks!

HttpsURLConnection connection = null;
BufferedReader reader = null;

try {
    URL url = new URL("https://example.com/GiveMeSomTextPlain");
    connection = (HttpsURLConnection) url.openConnection();
    connection.setConnectTimeout(9000);
    connection.setReadTimeout(11000);
    connection.connect();

    int resp = connection.getResponseCode();
    if (resp == 200) {

        reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

        // if( reader.ThereWillBeNoData() ){ // THIS IS WHAT I NEED
            // ...
        // }

        String line = "";
        while( ( line = reader.readLine() ) != null ){ // EXCEPTION IF EMPTY DATA
            // ...
        }

    }else{
        reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
    }

} catch (IOException e) {
    e.printStackTrace();
    // WE GET HERE AT EXCEPTION
} finally {
    if (connection != null) connection.disconnect();
    try {
        if (reader != null) reader.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

EDIT: ah, seems that it ends up in a timeout (which corresponds to the 11s I entered) but "empty" is an answer too, so how to avoid the timeout? (SEE MY RESPONSE)

STACK TRACE:

09-13 18:39:40.134 20925-21658/com.theapp D/ZZZ: BEFORE WHILE
09-13 18:39:51.155 20925-21658/com.theapp W/System.err: java.net.SocketTimeoutException: Read timed out
09-13 18:39:51.155 20925-21658/com.theapp W/System.err:     at com.android.org.conscrypt.NativeCrypto.SSL_read(Native Method)
09-13 18:39:51.155 20925-21658/com.theapp W/System.err:     at com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:690)
09-13 18:39:51.155 20925-21658/com.theapp W/System.err:     at java.io.BufferedInputStream.read(BufferedInputStream.java:283)
09-13 18:39:51.165 20925-21658/com.theapp W/System.err:     at com.android.okhttp.internal.http.UnknownLengthHttpInputStream.read(UnknownLengthHttpInputStream.java:39)
09-13 18:39:51.165 20925-21658/com.theapp W/System.err:     at java.io.InputStreamReader.read(InputStreamReader.java:233)
09-13 18:39:51.165 20925-21658/com.theapp W/System.err:     at java.io.BufferedReader.fillBuf(BufferedReader.java:145)
09-13 18:39:51.165 20925-21658/com.theapp W/System.err:     at java.io.BufferedReader.readLine(BufferedReader.java:397)
09-13 18:39:51.165 20925-21658/com.theapp W/System.err:     at com.theapp.Main.getMapData(Main.java:637)
09-13 18:39:51.165 20925-21658/com.theapp W/System.err:     at com.theapp.Main$2$2.run(Main.java:231)
09-13 18:39:51.165 20925-21658/com.theapp W/System.err:     at java.lang.Thread.run(Thread.java:841)
09-13 18:39:51.165 20925-21658/com.theapp D/ZZZ: EXCEPTION

Cause of the problem:

Content-Length was not sent by the server when no data.

This seems to be an ambiguous issue because it is not very clear whether Content-Length should be sent in this case. Web browsers handle the absence of Content-Length well, and seem to assume that it means 0. However, Android HttpsURLConnection does not, and keeps waiting until timeout. We may argue that no data should be a 204 HTTP response code and not a 200.

So if anyone has the same problem:

  • Either make sure the server sends a Content-Length: 0 when body is empty

  • Or send a 204 in that case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM