0

所以在我的 android 应用程序中,它使用 GET 来拉网页并下载文本,我执行:

private InputStream OpenHttpConnection(String urlString) throws IOException {
    Log.d("Networking", "InputStream called");
    InputStream in = null;
    int response = -1;

    URL url = new URL(urlString);
    URLConnection conn = url.openConnection();

    if(!(conn instanceof HttpURLConnection))
        throw new IOException("Not an HTTP connection");
    try {
        HttpURLConnection httpConn = (HttpURLConnection) conn;

        httpConn.setConnectTimeout(10000);
        httpConn.setReadTimeout(10000);
        httpConn.setAllowUserInteraction(false);
        httpConn.setInstanceFollowRedirects(true);
        httpConn.setRequestMethod("GET");
        httpConn.connect();
        response = httpConn.getResponseCode();
        if (response == HttpURLConnection.HTTP_OK) {
            in = httpConn.getInputStream();
        }
    }
    catch (Exception ex) {
            Log.d("Networking", "" + ex.getLocalizedMessage());
            throw new IOException("Error connecting");
        }
    return in;
}

private String DownloadText(String URL) {
    int BUFFER_SIZE = 2000;
    InputStream in = null;
    try {
        in = OpenHttpConnection(URL);
        } 
    catch (IOException e) {
        Log.d("Networking", "" + e.getLocalizedMessage());
        return "";
    }
    InputStreamReader isr = new InputStreamReader(in);
    int charRead;
    String str = "";
    char[] inputBuffer = new char[BUFFER_SIZE];
    try {
        while ((charRead = isr.read(inputBuffer))>0) {
            //---convert the chars to a String---
            String readString = String.copyValueOf(inputBuffer, 0, charRead);
            str += readString;
            inputBuffer = new char[BUFFER_SIZE]; }
        in.close();
    }
    catch (IOException e) {
        Log.d("Networking", "" + e.getLocalizedMessage());
        return "";
    }
    return str;
}

如果我调用 stringx = DownloadText("http://hello.com/whatever.txt"),这将非常有效,只要 what.txt 存在。

但是,如果它是 404s,它就会崩溃。这让我感到惊讶——404 仍在返回内容,确定吗?我已经进行了很多调试,它似乎执行了这一行:

    InputStreamReader isr = new InputStreamReader(in);

崩溃前。此行执行后没有任何内容。我试过使用 try {} catch (IOException) {} 来解决这个问题,但它说该行不会引发异常。

有没有人知道为什么这条线会导致这样的问题?我的应用程序几乎完成了,但是错误处理给我带来了问题!

非常感谢!

4

1 回答 1

4

您的这段代码:

    if (response == HttpURLConnection.HTTP_OK) {
        in = httpConn.getInputStream();
    }

防止in在您获得 404 时被分配。如果您获得除 HTTP_OK (200) 之外的任何内容,in则将为 null 并且您的 InputStreamReader 分配将失败。

要处理此错误,您可以使用以下模式:

class HTTPException extends IOException {
    private int responseCode;

    public HTTPException( final int responseCode ) {
        super();
        this.responseCode = responseCode;
    }

    public int getResponseCode() {
        return this.responseCode;
    }
}

然后按如下方式更改您的代码:

private InputStream OpenHttpConnection(String urlString) throws IOException {
    Log.d("Networking", "InputStream called");
    InputStream in = null;
    int response = -1;

    URL url = new URL(urlString);
    URLConnection conn = url.openConnection();

    if(!(conn instanceof HttpURLConnection))
        throw new IOException("Not an HTTP connection");
    try {
        HttpURLConnection httpConn = (HttpURLConnection) conn;

        httpConn.setConnectTimeout(10000);
        httpConn.setReadTimeout(10000);
        httpConn.setAllowUserInteraction(false);
        httpConn.setInstanceFollowRedirects(true);
        httpConn.setRequestMethod("GET");
        httpConn.connect();
        response = httpConn.getResponseCode();
        if (response == HttpURLConnection.HTTP_OK) {
            in = httpConn.getInputStream();
        } else { // this is new
            throw new HTTPException( response );
        }

    }
    catch (Exception ex) {
            Log.d("Networking", "" + ex.getLocalizedMessage());
            throw new IOException("Error connecting");
        }
    return in;
}

private String DownloadText(String URL) {
    int BUFFER_SIZE = 2000;
    InputStream in = null;
    try {
        in = OpenHttpConnection(URL);
        } 
    catch (IOException e) {
        Log.d("Networking", "" + e.getLocalizedMessage());
        return "";
    }
    InputStreamReader isr = new InputStreamReader(in);
    int charRead;
    String str = "";
    char[] inputBuffer = new char[BUFFER_SIZE];
    try {
        while ((charRead = isr.read(inputBuffer))>0) {
            //---convert the chars to a String---
            String readString = String.copyValueOf(inputBuffer, 0, charRead);
            str += readString;
            inputBuffer = new char[BUFFER_SIZE]; }
        in.close();
    }
    catch( HTTPException e ) {
        Log.d( String.format( "HTTP Response not ok: %d", e.getResponseCode() ) );
        // handle whatever else you need to handle here.
    }
    catch (IOException e) {
        Log.d("Networking", "" + e.getLocalizedMessage());
        return "";
    }
    return str;
}
于 2012-09-14T13:43:50.677 回答