Custom Java DNS Resolver with Apache HttpClient: InMemoryDnsResolver and SystemDefaultDnsResolver
This article demonstrates how to implement custom DNS resolvers in Java using Apache HttpClient's InMemoryDnsResolver and SystemDefaultDnsResolver classes, provides sample code for each, shows integration with a connection pool manager, and includes a simple test to verify hostname resolution.
After upgrading to a high‑performance test machine, the author encountered DNS resolution failures (domain names could not be resolved and IPs were inaccessible) and decided to create a custom Java DNS resolver.
InMemoryDnsResolver
The org.apache.http.impl.conn.InMemoryDnsResolver class is used for a straightforward, non‑load‑balanced DNS override. The following demo adds a mapping from fun.tester to 127.0.0.1 :
/**
* 重写Java自定义DNS解析器,非负载均衡
*
* @return
*/
private static DnsResolver getDnsResolver2() {
InMemoryDnsResolver dnsResolver = new InMemoryDnsResolver();
try {
dnsResolver.add("fun.tester", InetAddress.getByName("127.0.0.1"));
} catch (Exception e) {
e.printStackTrace();
}
return dnsResolver;
}With this resolver, any request to fun.tester will be directed to 127.0.0.1 .
SystemDefaultDnsResolver
The org.apache.http.impl.conn.SystemDefaultDnsResolver class represents the system default resolver, but its internal usage is not obvious. It is referenced in the asynchronous thread‑pool connection manager constructor:
/**
* 重写Java自定义DNS解析器,负载均衡
*
* @return
*/
private static DnsResolver getDnsResolver() {
return new SystemDefaultDnsResolver() {
@Override
public InetAddress[] resolve(final String host) throws UnknownHostException {
if (host.equalsIgnoreCase("fun.tester")) {
return new InetAddress[]{InetAddress.getByName("127.0.0.1")};
} else {
return super.resolve(host);
}
}
};
}Custom DnsResolver
Both implementations ultimately implement the org.apache.http.conn.DnsResolver interface. A fully custom resolver can be written directly:
/**
* 自定义本地DNS解析器实现
*
* @return
*/
private static DnsResolver getDnsResolver3() {
return new DnsResolver() {
@Override
public InetAddress[] resolve(final String host) throws UnknownHostException {
if (host.equalsIgnoreCase("fun.tester")) {
return new InetAddress[]{InetAddress.getByName("127.0.0.1")};
} else {
return InetAddress.getAllByName(host);
}
}
};
}Connection Pool Manager
To use a custom DnsResolver with Apache HttpClient, set it when constructing the connection‑pool manager.
Test
A simple local HTTP server is started on port 12345:
static void main(String[] args) {
def util = new ArgsUtil(args)
def server = getServerNoLog(util.getIntOrdefault(0, 12345))
server.response("Have Fun ~ Tester !")
def run = run(server)
waitForKey("fan")
run.stop()
}The test script sends ten GET requests to http://fun.tester:12345/ :
public static void main(String[] args) {
String url = "http://fun.tester:12345/";
def get = getHttpGet(url);
def funtester = {
fun {
getHttpResponse(get)
}
};
10.times {
funtester()
}
}Console output shows successful requests with HTTP 200 status and similar response times, confirming that all three resolver implementations work as expected in this functional test scenario. Future articles will explore load‑balancing implementations based on source analysis.
Have Fun ~ Tester !
FunTester
10k followers, 1k articles | completely useless
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.