最佳方案处理okhttp UnknownHostException("private hosts not resolved")
问题原因
OkHttp 出现 UnknownHostException("private hosts not resolved") 的原因是因为 OkHttp 默认情况下不会自动解析本地的私有域名(private hosts),即在 hosts 文件中定义的没有公共 DNS 解析的域名。这种私有域名通常是内部网络环境所使用的,公共的 DNS 并不能解析这些域名。
一般来说,这种情况会出现在企业内部网络或者局域网中。由于 OkHttp 默认情况下依赖于系统的 DNS 解析功能,当发起对私有域名的请求时,系统无法通过公共 DNS 解析该域名,导致 UnknownHostException 的异常。
要解决这个问题,需要通过自定义 DNS 解析器来告诉 OkHttp 如何解析私有域名。可以通过实现 Dns
接口并覆盖 lookup
方法来实现自定义 DNS 解析器,然后在构建 OkHttpClient
时使用自定义的 DNS 解析器来指定 OkHttp 如何解析域名。
另外,也可以通过修改系统的 hosts 文件(位于/etc/hosts
或C:\Windows\System32\drivers\etc\hosts
)将私有域名映射到对应的 IP 地址,这样系统就能正确解析私有域名了。
总结:OkHttp 出现 UnknownHostException("private hosts not resolved") 的原因是因为默认情况下无法解析私有域名,需要通过自定义 DNS 解析器或者修改 hosts 文件来解决这个问题。
解决方案
出现UnknownHostException("private hosts not resolved")的原因是由于 OkHttp 默认使用系统的 DNS 解析器,而系统的 DNS 解析器通常不会解析内网域名。因此,当尝试使用 OkHttp 访问内网域名时,就会出现该异常。 解决这个问题的方法是使用 OkHttp 的 Dns 接口自定义 DNS 解析器。你可以实现自己的 Dns 接口,然后将其设置到 OkHttp 的 OkHttpClient 中。 以下是一个示例代码来解决这个问题:
import okhttp3.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
public class CustomDns implements Dns {
@Override
public List lookup(String hostname) throws UnknownHostException {
if (hostname.equals("your.internal.hostname")) {
// 在这里返回内网域名对应的 IP 地址
return Arrays.asList(InetAddress.getAllByName("192.168.1.1"));
} else {
// 对于其它域名,使用系统默认的 DNS 解析
return Dns.SYSTEM.lookup(hostname);
}
}
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient.Builder()
.dns(new CustomDns())
.build();
Request request = new Request.Builder()
.url("http://your.internal.hostname/api")
.build();
try {
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
} catch (Exception e) {
e.printStackTrace();
}
}
}
在上面的示例中,我们创建了一个 CustomDns 类来实现 OkHttp 的 Dns 接口,并在其中实现了自定义的 DNS 解析逻辑。然后,在创建 OkHttpClient 对象时,通过 dns(new CustomDns())
方法将自定义的 DNS 解析器设置到 OkHttpClient 中。最后,发送请求时使用内网域名,OkHttp 就会使用我们自定义的解析器来解析域名。
这样,通过自定义 DNS 解析器,就可以解决 OkHttp 访问内网域名时出现 UnknownHostException("private hosts not resolved") 的问题。
具体例子
当在使用OkHttp时出现UnknownHostException("private hosts not resolved")错误时,通常是由于没有正确配置网络代理导致无法解析私有主机名。要正确解决这个问题,可以通过配置OkHttp的代理来允许访问私有主机名。 以下是一个示例代码,展示了如何在OkHttp中配置代理以解决UnknownHostException("private hosts not resolved")问题:
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class OkHttpExample {
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient.Builder()
.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxyHost", proxyPort)))
.build();
Request request = new Request.Builder()
.url("https://privatehostname.com/api/data")
.build();
try {
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上面的示例中,我们通过实例化一个OkHttpClient对象并使用proxy
方法来设置代理,其中proxyHost
是代理主机的地址,proxyPort
是代理的端口号。然后我们创建一个Request对象,指定需要访问的私有主机名的URL,并执行请求。
通过正确配置代理,我们可以使OkHttp能够访问私有主机名并避免出现UnknownHostException("private hosts not resolved")错误。