首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java HTTP 請求中的 DnsResolver 使用:預設 vs 自訂

     編輯:Java 相關知識

Java 網路程式設計:控制 DNS 解析行為的兩種方式

在發送 HTTP 請求時,JDK 內建的 java.net.InetAddress 使用系統預設 DNS 解析器。某些測試或特殊環境(如指定測試機 IP、繞過 DNS 快取)需要自訂解析邏輯。本文說明 java.net.spi.InetAddressResolver(JDK 18+)或第三方庫(如 OkHttp 的 Dns 介面)如何切換解析策略。

方式一:使用系統預設解析器(預設行為)

// JDK 內部自動使用系統 hosts、DNS 伺服器設定
// 開發者無需額外代碼,InetAddress.getByName("example.com") 即可
  • 讀取 /etc/hosts (Linux/macOS) 或 C:\Windows\System32\drivers\etc\hosts (Windows)。
  • 查詢系統配置的 DNS 伺服器(DHCP 取得或手動設定)。
  • 結果會被 JVM 快取(networkaddress.cache.ttl 控制 TTL)。

方式二:自訂 DnsResolver(以 OkHttp 為例)

OkHttp 提供 Dns 介面,可注入自訂解析邏輯:

import okhttp3.Dns;
import okhttp3.OkHttpClient;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;

public class CustomDns implements Dns {
    @Override
    public List lookup(String hostname) throws UnknownHostException {
        if ("dev4.baike.xx.com".equals(hostname)) {
            return List.of(InetAddress.getByName("1.1.1.1"));
        }
        if ("baike.baidu.com".equals(hostname)) {
            return List.of(InetAddress.getByName("2.2.2.2"));
        }
        // 其餘域名回退至系統預設
        return Dns.SYSTEM.lookup(hostname);
    }
}

// 使用
OkHttpClient client = new OkHttpClient.Builder()
    .dns(new CustomDns())
    .build();

應用場景

場景解決方案
本地開發對應測試環境 IP自訂 Dns 將特定域名解析至測試機 IP
繞過 DNS 污染/劫持指定可信 DNS 伺服器 IP(如 8.8.8.8)
單元測試模擬網路Mock Dns 回傳固定 IP,不依賴真實網路
灰度發布/流量切分依權重解析到不同版本服務 IP

JDK 18+ 內建 SPI:InetAddressResolverProvider

JDK 18 引入 java.net.spi.InetAddressResolverProvider,可透過 SPI 機制替換全域解析器,無需第三方庫:

// META-INF/services/java.net.spi.InetAddressResolverProvider
com.example.MyResolverProvider

// MyResolverProvider 實作 get() 回傳自訂 InetAddressResolver

注意事項

  • 自訂解析器需處理 IPv4/IPv6、CNAME 遞迴、解析失敗重試等細節。
  • JVM DNS 快取(sun.net.inetaddr.ttl)可能導致自訂解析器不生效,需設定 -Dsun.net.inetaddr.ttl=0 關閉快取。
  • Android 平台請使用 okhttp3.Dns 或 android.net.ConnectivityManager 相關 API。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved