Atul Goyal
Atul Goyal

Reputation: 3521

Send Post request along with HttpHeaders on Android

I need to post data to server (with "referer" header field) and load the response in Webview.

Now, there are different methods (from Android WebView) to do parts of it, like there is:

void loadUrl(String url, Map<String, String> additionalHttpHeaders)

Loads the given URL with the specified additional HTTP headers.

void loadData(String data, String mimeType, String encoding)

Loads the given data into this WebView using a 'data' scheme URL.

void postUrl(String url, byte[] postData)

Loads the URL with postData using "POST" method into this WebView.

loadUrl() allows to send HttpHeaders but doesn't allow to send post data, other methods seem to be not allowing to send HttpHeaders. Am I missing something or what I am trying is not possible?

Upvotes: 15

Views: 8930

Answers (2)

Alex Cohn
Alex Cohn

Reputation: 57173

You can use a custom class that inherits from WebView, or if you prefer, you can add an extension function. The logic is essentially the same:

private fun WebView.postUrl(postUrl: String, postData: ByteArray, additionalHttpHeaders: MutableMap<String, String>) {

    val savedWebViewClient = getWebViewClient()

    webViewClient = object : WebViewClient() {
        override fun shouldInterceptRequest(view: WebView, url: String): WebResourceResponse? {

            if (url != postUrl) {
                view.post {
                    webViewClient = savedWebViewClient
                }
                return savedWebViewClient?.shouldInterceptRequest(view, url)
            }

            Log.d("WebView extension", "post ${postData.decodeToString()} to ${url}")
            val httpsUrl = URL(url)
            val conn: HttpsURLConnection = httpsUrl.openConnection() as HttpsURLConnection
            conn.requestMethod = "POST"
            additionalHttpHeaders.forEach { header ->
                conn.addRequestProperty(header.key, header.value)
            }

            conn.outputStream.write(postData)
            conn.outputStream.close()

            val responseCode = conn.responseCode
            Log.d("WebView extension", "responseCode = ${responseCode} ${conn.contentType}")
            view.post {
                webViewClient = savedWebViewClient
            }

            // typical conn.contentType is "text/html; charset=UTF-8"
            return WebResourceResponse(conn.contentType.substringBefore(";"), "utf-8", conn.inputStream)
        }
    }

    loadUrl(postUrl, additionalHttpHeaders)
}

The code above was redacted for brevity, with most error checking hidden. To work for API below level 26, I use reflection to extract the savedWebViewClient.

In real life, you also want to override the new shouldInterceptRequest(view: WebView, request: WebResourceRequest) method, and delegate all other methods of your WebViewClient to the savedWebViewClient. Probably a PostWithHeadersWebView class (which overrides also setWibViewClient()) could make your life easier.

Upvotes: 0

ntv1000
ntv1000

Reputation: 626

You can execute the HttpPost manually like this:

HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yoursite.com/postreceiver");

// generating your data (AKA parameters)
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("ParameterName", "ParameterValue"));
// ...

// adding your headers
httppost.setHeader("HeaderName", "HeaderValue");
// ...

// adding your data
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

HttpResponse response = httpclient.execute(httppost);

Get the response as String:

BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
StringBuilder builder = new StringBuilder();
for (String line = null; (line = reader.readLine()) != null;) {
    builder.append(line).append("\n");
}
String html = builder.toString();

Now you can put the html into yourWebView by using loadData():

yourWebView.loadData(html ,"text/html", "UTF-8");

Upvotes: 1

Related Questions