2012-07-25 4 views
7

java.net.InetAddress löst Host-Namen der lokalen Maschine Standard-Host-Name-Resolver standardmäßig mit:Wie wird die Hostnamenauflösung für die Verwendung eines benutzerdefinierten DNS-Servers in Java konfiguriert?

Hostnamen-zu-IP-Adressauflösung durch die Verwendung einer Kombination von lokalen Maschinen Konfigurationsinformationen und Netzwerk erfolgt Dienste wie Namensgebung das Domain Name System (DNS) und der Network Information Service (NIS). Die bestimmten Benennungsdienste, die verwendet werden, sind . Standardmäßig ist das lokale Gerät als konfiguriert. Für jeden Hostnamen wird die entsprechende IP-Adresse zurückgegeben. [source]

Wie können wir dieses Verhalten konfigurieren, ohne den lokalen Rechner des Standardhostnamen Resolver zu modifizieren?

Zum Beispiel ist es sowieso zu konfigurieren java.net.InetAddress so, dass es Hostnamen durch OpenDNS (208.67.222.222, 208.67.220.220) oder Google Public DNS (2001: 4860: 4860 :: 8888, 2001: 4860: 4860: : 8844)?

Oder ist die einzige Lösung zum expliziten Erstellen von DNS-Paketanforderungen, senden Sie sie an die Server über java.net.DatagramSocket oder java.net.Socket, und analysieren Sie die Antworten?

Antwort

8

Java 9 hat diese Funktion entfernt. Sie müssen eine DNS-Client-Bibliothek eines Drittanbieters verwenden.

Wenn Sie mit Java 8 oder älter Sie tun können:

Sie können das System Eigenschaft sun.net.spi.nameservice.nameservers wie this site. dokumentiert ist

+1

Wie auf derselben Website dokumentiert: "Diese Eigenschaften werden in zukünftigen Versionen möglicherweise nicht unterstützt." Gibt es einen anderen Weg, das zu erreichen? – bernatp

+2

Nein. Wenn Sie 'java.net.InetAddress' verwenden möchten. Wenn Sie einen anderen Mechanismus verwenden, können Sie natürlich eine DNS-Bibliothek eines Drittanbieters verwenden (z. B. [dnsjava] (http://www.dnsjava.org/)). Der einzige wirkliche Grund für die Änderung der Eigenschaften ist, dass Oracle die 'java.net' -Implementierung in einer zukünftigen Version von Java überarbeitet. Wenn dies geschieht, werden sie wahrscheinlich auch zu diesem Zeitpunkt eine neue Lösung für dieses Problem bieten. – Pace

+0

Sie überholten 'java.net' in Java 9, so dass die 'sun.net'-Klassen, die es gab, nicht mehr existieren. – ndm13

1

Hier ist der Code, den ich DNS ein foo Systemnamen zu hart Code geschrieben Auflösung in Java, damit Testfälle bestanden werden. Der Vorteil besteht darin, Ihre spezifischen Einträge an die Standard-Java-Runtime-DNS-Auflösung anzufügen.

Ich empfehle nicht in der Produktion zu laufen. Forced Reflective Access und Java Runtime nicht öffentliche Implementierungsklassen werden verwendet!

private static final String FOO_IP = "10.10.8.111"; 

/** Fake "foo" DNS resolution */ 
@SuppressWarnings("restriction") 
public static class MyHostNameService implements sun.net.spi.nameservice.NameService { 
    @Override 
    public InetAddress[] lookupAllHostAddr(String paramString) throws UnknownHostException { 
     if ("foo".equals(paramString) || "foo.domain.tld".equals(paramString)) { 
      final byte[] arrayOfByte = sun.net.util.IPAddressUtil.textToNumericFormatV4(FOO_IP); 
      final InetAddress address = InetAddress.getByAddress(paramString, arrayOfByte); 
      return new InetAddress[] { address }; 
     } else { 
      throw new UnknownHostException(); 
     } 
    } 
    @Override 
    public String getHostByAddr(byte[] paramArrayOfByte) throws UnknownHostException { 
     throw new UnknownHostException(); 
    } 
} 

static { 
    // Force to load fake hostname resolution for tests to pass 
    try { 
     List<sun.net.spi.nameservice.NameService> nameServices = 
      (List<sun.net.spi.nameservice.NameService>) 
      org.apache.commons.lang3.reflect.FieldUtils.readStaticField(InetAddress.class, "nameServices", true); 
     nameServices.add(new MyHostNameService()); 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } 
} 

Hoffe das hilft, aber wieder, mit Vorsicht verwendet werden!

Verwandte Themen