Is there a way to view the http response headers in an Activity once a web page has been loaded in a WebView? Seems like this should be possible, but I can't find any methods that expose the headers.
To view the request or response HTTP headers in Google Chrome, take the following steps : In Chrome, visit a URL, right click , select Inspect to open the developer tools. Select Network tab. Reload the page, select any HTTP request on the left panel, and the HTTP headers will be displayed on the right panel.
Simple Way to Get HTTP Response Header in Java – conn. getHeaderFields() public Map<String,List<String>> getHeaderFields() Returns an unmodifiable Map of the header fields. The Map keys are Strings that represent the response-header field names.
Neither WebView
nor WebViewClient
provide methods to do that, Though, you can try to implement that manually. You can do something like this:
private WebView webview; public void onCreate(Bundle icicle){ // bla bla bla // here you initialize your webview webview = new WebView(this); webview.setWebViewClient(new YourWebClient()); } // this will be the webclient that will manage the webview private class YourWebClient extends WebViewClient{ // you want to catch when an URL is going to be loaded public boolean shouldOverrideUrlLoading (WebView view, String urlConection){ // here you will use the url to access the headers. // in this case, the Content-Length one URL url; URLConnection conexion; try { url = new URL(urlConection); conexion = url.openConnection(); conexion.setConnectTimeout(3000); conexion.connect(); // get the size of the file which is in the header of the request int size = conexion.getContentLength(); } // and here, if you want, you can load the page normally String htmlContent = ""; HttpGet httpGet = new HttpGet(urlConection); // this receives the response HttpResponse response; try { response = httpClient.execute(httpGet); if (response.getStatusLine().getStatusCode() == 200) { // la conexion fue establecida, obtener el contenido HttpEntity entity = response.getEntity(); if (entity != null) { InputStream inputStream = entity.getContent(); htmlContent = convertToString(inputStream); } } } catch (Exception e) {} webview.loadData(htmlContent, "text/html", "utf-8"); return true; } public String convertToString(InputStream inputStream){ StringBuffer string = new StringBuffer(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; try { while ((line = reader.readLine()) != null) { string.append(linea + "\n"); } } catch (IOException e) {} return string.toString(); } }
I can't test it right now, but that's basically what you could do (it's very crazy though :).
inspired by Cristian answer I needed to intercept AJAX calls webview is doing, where I needed to intercept response headers to get some information (cart item count in e-commerce app), which I needed to leverage in app. As the app is using okhttp I've ended up doing this and it's working:
@TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { Log.i(TAG,"shouldInterceptRequest path:"+request.getUrl().getPath()); WebResourceResponse returnResponse = null; if (request.getUrl().getPath().startsWith("/cart")) { // only interested in /cart requests returnResponse = super.shouldInterceptRequest(view, request); Log.i(TAG,"cart AJAX call - doing okRequest"); Request okRequest = new Request.Builder() .url(request.getUrl().toString()) .post(null) .build(); try { Response okResponse = app.getOkHttpClient().newCall(okRequest).execute(); if (okResponse!=null) { int statusCode = okResponse.code(); String encoding = "UTF-8"; String mimeType = "application/json"; String reasonPhrase = "OK"; Map<String,String> responseHeaders = new HashMap<String,String>(); if (okResponse.headers()!=null) { if (okResponse.headers().size()>0) { for (int i = 0; i < okResponse.headers().size(); i++) { String key = okResponse.headers().name(i); String value = okResponse.headers().value(i); responseHeaders.put(key, value); if (key.toLowerCase().contains("x-cart-itemcount")) { Log.i(TAG,"setting cart item count"); app.setCartItemsCount(Integer.parseInt(value)); } } } } InputStream data = new ByteArrayInputStream(okResponse.body().string().getBytes(StandardCharsets.UTF_8)); Log.i(TAG, "okResponse code:" + okResponse.code()); returnResponse = new WebResourceResponse(mimeType,encoding,statusCode,reasonPhrase,responseHeaders,data); } else { Log.w(TAG,"okResponse fail"); } } catch (IOException e) { e.printStackTrace(); } } return returnResponse; }
I hope this may be helpful to others and if somebody has a suggestions for improvement I would be grateful. Unfortunately it's compatible only with LOLLIPOP and higher as from this version you can access/return headers using WebResourceRequest, which was needed for my case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With