Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access the http response headers in a WebView?

Tags:

android

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.

like image 699
tronman Avatar asked Jun 28 '10 16:06

tronman


People also ask

How do I view HTTP 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.

How do I return a response header in Java?

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.


2 Answers

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 :).

like image 113
Cristian Avatar answered Sep 23 '22 18:09

Cristian


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.

like image 31
ursimon Avatar answered Sep 22 '22 18:09

ursimon