android - 如何处理 WebViewClient.shouldInterceptRequest() 中的 IOException

标签 android android-webview httprequest ioexception

我正在尝试拦截来自 WebView 的请求,以便我可以注入(inject)额外的 header 。我正在将 WebViewClient 应用于 WebView 并覆盖 shouldInterceptRequest()

shouldInterceptRequest() 中,我打开连接,添加 header ,然后在 WebResourceResponse 中返回打开的流。

如果连接的初始打开失败,我不清楚应该如何处理 IOException。

final Map<String, String> extraHeaders = getExtraHeaders(intent);
webview.setWebViewClient(new WebViewClient() {
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        final Uri uri = request.getUrl();

        try {
            URL           url = new URL(uri.toString());
            URLConnection con = url.openConnection();
            for (Map.Entry<String, String> h : extraHeaders.entrySet()) {
                con.addRequestProperty(h.getKey(), h.getValue());
            }
            final String contentType = con.getContentType().split(";")[0];
            final String encoding    = con.getContentEncoding();
            return new WebResourceResponse(contentType, encoding, con.getInputStream());
        } catch (IOException e) {
            // what should we do now?
            e.printStackTrace();
        }

        return super.shouldInterceptRequest(view, request);
    }
});

我不能不捕获它,因为它是一个已检查的异常,不是 shouldInterceptRequest() 签名的一部分。

我不能将它包装在一个未经检查的异常中,因为它不会被 WebView 捕获并终止应用程序。

如果我捕获并忽略异常,并默认使用 super 方法(仅返回 null),则 WebView 将继续其默认行为并尝试发送请求(没有我的额外标题)。这是不可取的,因为 WebView 自己的连接尝试实际上可能会成功,并且缺少 header 会导致更多问题。

似乎没有办法表明拦截失败,应该中止请求。

在这里最好的事情是什么?


我尝试返回一个模拟失败响应,但这不被视为错误。 WebView 显示包含响应内容(来自异常的错误消息)的页面,并且不会调用 WebViewClient 的 onReceivedError()onReceivedHttpError() 回调。

} catch (IOException e) {
    InputStream is = new ByteArrayInputStream(e.getMessage().getBytes());
    return new WebResourceResponse("text/plain", "UTF-8", 500, "Intercept failed",
                                   Collections.<String, String>emptyMap(),
                                   is);
}

最佳答案

您可以尝试实例化一个新的 WebResourceError然后调用WebViewClient.onReceivedError .从未尝试过这样的事情,但这就是它的样子:

} catch (final IOException e) {
    WebResourceError wre = new WebResourceError(){
        @Override
        public CharSequence getDescription (){
            return e.toString(); 
        }

        @Override
        public int getErrorCode (){
            return WebViewClient.ERROR_CONNECT;
        }
    };

    onReceivedError(view, request, wre);

    return true;
}

还有一个 deprecated version of onReceivedError如果您不想或不能实例化 WebResourceError,您可以使用。

关于android - 如何处理 WebViewClient.shouldInterceptRequest() 中的 IOException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34945021/

相关文章:

Android - 带小数分隔符的数字键盘

android - 从存储在可绘制文件夹中的位图中获取位图信息

android-webview 不左右移动/平移/滚动

python - 带有 Python 'Requests' 模块的代理

security - 只允许从特定的 html 页面访问图像

android - 是否有 Java 库来简化 Google Cloud Messaging?

java - Mockito doAnswer 因未知原因抛出 InvalidUseOfMatchersException

android - 如何从 Android WebView 中的远程 URL 访问本地资源?

android - 如何在 HTML 中而不是在 View 中滚动?

ios - 如何间隔和异步发送HTTP请求