All Products
Search
Document Center

HTTPDNS:Integrate HTTPDNS with Android WebView and OkHttp

Last Updated:Jun 04, 2026

The Android SDK integration flow covers Android SDK import, configuration, IP resolution, and network library integration. This topic describes how to integrate HTTPDNS in Android WebView using OkHttp.

1. Background

Alibaba Cloud HTTPDNS helps prevent DNS hijacking by bypassing system DNS resolution. You call the HTTPDNS API to resolve domain names, which reduces or eliminates hijacking risks.

In WebView, you can intercept web page network requests and route them through the native layer (App). During this process, HTTPDNS resolution replaces system DNS to prevent hijacking.

This topic focuses on OkHttp, the mainstream Android network library.

Important
  • This topic provides a reference solution. The code samples are for reference only and are not intended for direct use in production. Evaluate carefully before implementing.

  • Android systems vary by vendor. Test this solution in a non-production environment first. For questions, contact Technical support.

  • This topic covers HTTPDNS in WebView scenarios only. For HTTPDNS resolution fundamentals, review Android SDK integration.

2. GET-only interception: limitations and impact

Android's WebViewClient.shouldInterceptRequest() method provides details only for GET requests. For POST and other methods, the request body is unavailable, making full HTTPDNS interception impossible.

GET-only interception still provides significant value:

  1. Static resources use GET requests. Web page resources (images, scripts, stylesheets) load through GET requests. Intercepting these with HTTPDNS covers most resource loading and significantly reduces hijacking risk.

  2. Many API calls use GET. Query and cacheable API endpoints typically use GET requests, which HTTPDNS interception also protects.

  3. HTTPDNS improves CDN routing accuracy. CDN performance depends on accurate DNS resolution. HTTPDNS bypasses system DNS hijacking and ensures resolution points to the optimal CDN node, improving access speed.

  4. GET interception covers most hijacking scenarios. DNS hijacking typically targets popular and static resource domains, which are almost exclusively accessed through GET requests. GET-only HTTPDNS covers the vast majority of traffic, achieving 80% or higher protection.

Although only GET requests can be intercepted in WebView, this covers the majority of traffic and enables more accurate CDN routing, significantly improving both security and performance.

3. Demo code

HTTPDNS+WebView+OkHttp best practices sample code is in the WebView+HTTPDNS+OkHttp Android Demo.

4. Implementation

The following steps describe how to integrate HTTPDNS with OkHttp and WebView to intercept and process web page requests in the native layer.

4.1 OkHttp configuration

4.1.1 Custom DNS resolution

OkHttp's Dns interface lets you customize DNS resolution. Integrate HTTPDNS through this interface:

OkHttpClient.Builder()
        // Customize the DNS resolution logic.
        .dns(object : Dns {
            override fun lookup(hostname: String): List<InetAddress> {
                val inetAddresses = mutableListOf<InetAddress>()
                HttpDns.getService(accountId)
                    .getHttpDnsResultForHostSyncNonBlocking(hostname, RequestIpType.auto)?.apply {
                    if (!ipv6s.isNullOrEmpty()) {
                        for (i in ipv6s.indices) {
                            inetAddresses.addAll(
                                InetAddress.getAllByName(ipv6s[i]).toList()
                            )
                        }
                    } else if (!ips.isNullOrEmpty()) {
                        for (i in ips.indices) {
                            inetAddresses.addAll(
                                InetAddress.getAllByName(ips[i]).toList()
                            )
                        }
                    }
                }

                if (inetAddresses.isEmpty()) {
                    inetAddresses.addAll(Dns.SYSTEM.lookup(hostname))
                }
                return inetAddresses
            }
        })
        .build()
new OkHttpClient.Builder()
        // Customize DNS resolution logic.
        .dns(new Dns() {
            @NonNull
            @Override
            public List<InetAddress> lookup(@NonNull String hostname) throws UnknownHostException {
                ArrayList<InetAddress> inetAddresses = new ArrayList<>();
                HTTPDNSResult result = HttpDns.getService(accountiD)
                        .getHttpDnsResultForHostSync(hostname, RequestIpType.auto);
                if (result != null) {
                    if (result.getIpv6s() != null && result.getIpv6s().length > 0) {
                        for (int i = 0; i < result.getIpv6s().length; i++) {
                            InetAddress[] ipV6InetAddresses = InetAddress.getAllByName(result.getIpv6s()[i]);
                            inetAddresses.addAll(Arrays.asList(ipV6InetAddresses));
                        }

                    } else if (result.getIps() != null && result.getIps().length > 0) {
                        for (int i = 0; i < result.getIps().length; i++) {
                            InetAddress[] ipV4InetAddresses = InetAddress.getAllByName(result.getIps()[i]);
                            inetAddresses.addAll(Arrays.asList(ipV4InetAddresses));
                        }
                    }
                }
                if (inetAddresses.isEmpty()) {
                    inetAddresses.addAll(Dns.SYSTEM.lookup(hostname));
                }
                return inetAddresses;
            }
        })
        .build();
Note

Fall back to local DNS when HTTPDNS resolution fails.

4.1.2 Disable redirection

This solution delegates redirection to WebView's default handler instead of the network layer, preventing cookie and resource loading errors in redirect scenarios:

OkHttpClient.Builder()
    .followRedirects(false)      // Disable HTTP redirection.
    .followSslRedirects(false)   // Disable HTTPS redirection.
    .build()
new OkHttpClient.Builder()
    .followRedirects(false)      // Disable HTTP redirection.
    .followSslRedirects(false)   // Disable HTTPS redirection.
    .build();
Note

In untrusted network environments, redirected requests can still be tampered with. Implement security protection on the client side.

4.2 WebView intercepts network requests

4.2.1 Implement WebViewClient

WebView's WebViewClient interface lets you intercept resource loading by overriding shouldInterceptRequest(). This routes web page requests through the native layer (OkHttp) and returns results to WebView:

webview.webViewClient = object : WebViewClient() {
    override fun shouldInterceptRequest(
        view: WebView?,
        request: WebResourceRequest?
    ): WebResourceResponse? {
        if (shouldIntercept(request)) {
            return getResponseByOkHttp(request)
        }
        return super.shouldInterceptRequest(view, request)
    }
}
webview.setWebViewClient(new WebViewClient(){
    @Nullable
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        if (shouldIntercept(request)) {
            return getResponseByOkHttp(request);
        }
        return super.shouldInterceptRequest(view, request);
    }
});

4.2.2 Determine whether to intercept requests

The shouldIntercept() method intercepts requests only when:

  • The protocol is http or https. Other protocols are handled by WebView directly.

  • The method is GET.

Sample code:

private fun shouldIntercept(webResourceRequest: WebResourceRequest?): Boolean {
    if (webResourceRequest == null) {
        return false
    }
    val url = webResourceRequest.url ?: return false
    // Non-HTTP requests are not intercepted.
    if ("https" != url.scheme && "http" != url.scheme) {
        return false
    }
    // Only GET requests are intercepted.
    if ("GET".equals(webResourceRequest.method, true)) {
        return true
    }
    return false
}
private boolean shouldIntercept(WebResourceRequest request) {
    if (request == null || request.getUrl() == null) {
        return false;
    }
    // Non-HTTP requests are not intercepted.
    if (!"http".equals(request.getUrl().getScheme()) && !"https".equals(request.getUrl().getScheme())) {
        return false;
    }
    // Only GET requests are intercepted.
    if ("GET".equalsIgnoreCase(request.getMethod())) {
        return true;
    }

    return false;
}

4.2.3 Use OkHttp for network requests

  • Use OkHttp to send network requests using the request URL, headers, and other information.

  • Wrap the response in a WebResourceResponse and return it to WebView.

Sample code:

private fun getResponseByOkHttp(webResourceRequest: WebResourceRequest?): WebResourceResponse? {
    if (webResourceRequest == null) {return null}
    try {
        val url = webResourceRequest.url.toString()
        val requestBuilder =
            Request.Builder().url(url).method(webResourceRequest.method, null)
        val requestHeaders = webResourceRequest.requestHeaders
        if (!requestHeaders.isNullOrEmpty()) {
            requestHeaders.forEach {
                requestBuilder.addHeader(it.key, it.value)
            }
        }
        val response = okHttpClient.newCall(requestBuilder.build()).execute()
        val code = response.code
        if (code != 200) {
            return null
        }
        val body = response.body
        if (body != null) {
            val contentType = body.contentType()
            val encoding = contentType?.charset()
            val mediaType = contentType?.toString()
            var mimeType = "text/plain"
            if (!TextUtils.isEmpty(mediaType)) {
                val mediaTypeElements = mediaType?.split(";")
                if (!mediaTypeElements.isNullOrEmpty()) {
                    mimeType = mediaTypeElements[0]
                }
            }
            val responseHeaders = mutableMapOf<String, String>()
            for (header in response.headers) {
                responseHeaders[header.first] = header.second
            }
            var message = response.message
            if (message.isBlank()) {
                message = "OK"
            }
            val resourceResponse =
                WebResourceResponse(mimeType, encoding?.name(), body.byteStream())
            resourceResponse.responseHeaders = responseHeaders
            resourceResponse.setStatusCodeAndReasonPhrase(code, message)
            return resourceResponse
        }
    } catch (e: Throwable) {
        e.printStackTrace()
    }
    return null
}
private WebResourceResponse getResponseByOkHttp(WebResourceRequest request) {
    try {
        String url = request.getUrl().toString();
        Request.Builder requestBuilder = new Request.Builder()
                .url(url)
                .method(request.getMethod(), null);
        Map<String, String> requestHeaders = request.getRequestHeaders();
        if (requestHeaders != null) {
            for (Map.Entry<String, String> entry : requestHeaders.entrySet()) {
                requestBuilder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        Response response = okHttpClient.newCall(requestBuilder.build()).execute();
        if (200 != response.code()) {
            return null;
        }
        ResponseBody body = response.body();
        if (body != null) {
            MediaType contentType = body.contentType();
            if (contentType != null) {
                Charset encoding = contentType.charset();
                String mediaType = contentType.toString();
                String mimeType = "text/plain";
                if (!TextUtils.isEmpty(mediaType)) {
                    String[] mediaTypeElements = mediaType.split(";");
                    if (mediaTypeElements.length > 0) {
                       mimeType = mediaTypeElements[0];
                    }
                }
                Map<String, String> responseHeaders = new HashMap<>();
                for (String key : response.headers().names()) {
                    responseHeaders.put(key, response.header(key));
                }
                String message = response.message();
                if (TextUtils.isEmpty(message)) {
                    message = "OK";
                }
                WebResourceResponse resourceResponse = new WebResourceResponse(mimeType, encoding.name(), body.byteStream());
                resourceResponse.setResponseHeaders(responseHeaders);
                resourceResponse.setStatusCodeAndReasonPhrase(response.code(), message);
                return resourceResponse;
            }

        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

5. Verification

After integration, follow Verify a successful network library integration to test with hijack impersonation or fault injection testing.

6. Summary

  • HTTPDNS reduces DNS hijacking risk. Intercepting WebView requests through OkHttp with HTTPDNS significantly improves DNS resolution security.

  • WebView limits interception to GET requests, but this covers most scenarios including static resource loading and common GET API calls.

  • Test before production. Deploy this solution in a test environment first, monitor for exceptions, and customize as needed for your business requirements.

For questions or technical support, contact Technical support.