Geolocation über IP in Java

Geolocation nach IP in Java

1. Einführung

In diesem Artikel erfahren Sie, wie Sie mithilfe der MaxMind GeoIP2-Java-API mit der kostenlosen GeoLite2-Datenbank geografische Standortdaten von einer IP-Adresse abrufen können.

Wir werden dies auch anhand einer einfachen Spring MVC-Webdemoanwendung in Aktion sehen.

2. Anfangen

Um zu beginnen, müssen Sie die GeoIP2-API und die GeoLite2-Datenbank von MaxMind herunterladen.

2.1. Maven-Abhängigkeit

Fügen Sie derpom.xml-Datei Folgendes hinzu, um die MaxMind GeoIP2-API in Ihr Maven-Projekt aufzunehmen:


    com.maxmind.geoip2
    geoip2
    2.8.0

Um die neueste Version der API zu erhalten, finden Sie sie aufMaven Central.

2.2. Herunterladen der Datenbank

Als Nächstes müssen Sie dieGeoLite2 databaseherunterladen. Für dieses Tutorial verwenden wir die Binärversion der GeoLite2 City-Datenbank.

Nachdem Sie das Archiv entpackt haben, haben Sie eine Datei mit dem NamenGeoLite2-City.mmdb. Dies ist eine Datenbank mit Zuordnungen von IP-Adressen im proprietären MaxMind-Binärformat.

3. Verwenden der GeoIP2-Java-API

Verwenden Sie die GeoIP2-Java-API, um Standortdaten für eine bestimmte IP-Adresse aus der Datenbank abzurufen. Erstellen wir zunächst einDatabaseReader, um die Datenbank abzufragen:

File database = new File(dbLocation);
DatabaseReader dbReader = new DatabaseReader.Builder(database).build();

Verwenden Sie als Nächstes die Methodecity(), um die Stadtdaten für eine IP-Adresse abzurufen:

CityResponse response = dbReader.city(ipAddress);

Das ObjektCityResponseenthält mehrere andere Informationen als nur den Namen der Stadt. Hier ist ein Beispiel für einen JUnit-Test, der zeigt, wie Sie die Datenbank öffnen, die Stadtinformationen für eine IP-Adresse abrufen und diese Informationen ausCityResponse extrahieren:

@Test
public void givenIP_whenFetchingCity_thenReturnsCityData()
  throws IOException, GeoIp2Exception {
    String ip = "your-ip-address";
    String dbLocation = "your-path-to-mmdb";

    File database = new File(dbLocation);
    DatabaseReader dbReader = new DatabaseReader.Builder(database)
      .build();

    InetAddress ipAddress = InetAddress.getByName(ip);
    CityResponse response = dbReader.city(ipAddress);

    String countryName = response.getCountry().getName();
    String cityName = response.getCity().getName();
    String postal = response.getPostal().getCode();
    String state = response.getLeastSpecificSubdivision().getName();
}

4. Verwenden von GeoIP in einer Webanwendung

Schauen wir uns eine Beispiel-Webanwendung an, die Geolokalisierungsdaten von der öffentlichen IP-Adresse eines Benutzers abruft und den Standort auf einer Karte anzeigt.

Wir werden mit einembasic Spring Web MVC Application beginnen. Dann schreiben wir einController, das eine IP-Adresse in einer POST-Anforderung akzeptiert und eine JSON-Antwort zurückgibt, die Stadt, Breite und Länge enthält, die von der GeoIP2-API abgeleitet wurden.

Schließlich schreiben wir HTML und JavaScript, die die öffentliche IP-Adresse des Benutzers in das Formular laden, eine Ajax-POST-Anfrage an unsereControllerenden und das Ergebnis in Google Maps anzeigen.

4.1. Die Antwortentitätsklasse

Beginnen wir mit der Definition der Klasse, die die Geolokalisierungsantwort enthält:

public class GeoIP {
    private String ipAddress;
    private String city;
    private String latitude;
    private String longitude;
    // constructors, getters and setters...
}

4.2. Die Serviceklasse

Schreiben wir nun die Serviceklasse, die die Geolokalisierungsdaten mithilfe der GeoIP2-Java-API und der GeoLite2-Datenbank abruft:

public class RawDBDemoGeoIPLocationService {
    private DatabaseReader dbReader;

    public RawDBDemoGeoIPLocationService() throws IOException {
        File database = new File("your-mmdb-location");
        dbReader = new DatabaseReader.Builder(database).build();
    }

    public GeoIP getLocation(String ip)
      throws IOException, GeoIp2Exception {
        InetAddress ipAddress = InetAddress.getByName(ip);
        CityResponse response = dbReader.city(ipAddress);

        String cityName = response.getCity().getName();
        String latitude =
          response.getLocation().getLatitude().toString();
        String longitude =
          response.getLocation().getLongitude().toString();
        return new GeoIP(ip, cityName, latitude, longitude);
    }
}

4.3. Der Federregler

Werfen wir einen Blick aufController für Spring MVC, das den Anforderungsparameter "ipAddress" an unsere Serviceklasse sendet, um die Geolocation-Antwortdaten abzurufen:

@RestController
public class GeoIPTestController {
    private RawDBDemoGeoIPLocationService locationService;

    public GeoIPTestController() throws IOException {
        locationService = new RawDBDemoGeoIPLocationService();
    }

    @PostMapping("/GeoIPTest")
    public GeoIP getLocation(
      @RequestParam(value="ipAddress", required=true) String ipAddress
    ) throws Exception {

        GeoIPLocationService locationService
          = new RawDBDemoGeoIPLocationService();
        return locationService.getLocation(ipAddress);
    }
}

4.4. Das HTML-Formular

Fügen wir den Front-End-Code hinzu, um unsere SpringController,aufzurufen, beginnend mit einem HTML-Formular, das die IP-Adresse enthält:


    
...

4.5. Laden der öffentlichen IP-Adresse auf den Client

Füllen Sie nun das Textfeld "ipAddress" mit der öffentlichen IP-Adresse des Benutzers unter Verwendung von jQuery und der JavaScript-API vonipify.orgvor:



4.6. Senden der Ajax POST-Anfrage

Wenn das Formular gesendet wird, senden wir eine Ajax-POST-Anfrage an SpringController, um die JSON-Antwort mit Geolokalisierungsdaten abzurufen:

$( "#ipForm" ).submit(function( event ) {
    event.preventDefault();
    $.ajax({
        url: "GeoIPTest",
        type: "POST",
        contentType:
         "application/x-www-form-urlencoded; charset=UTF-8",
        data: $.param( {ipAddress : $("#ip").val()} ),
        complete: function(data) {},
        success: function(data) {
            $("#status").html(JSON.stringify(data));
            if (data.ipAddress !=null) {
                showLocationOnMap(data);
            }
        },
        error: function(err) {
            $("#status").html("Error:"+JSON.stringify(data));
            },
        });
});

4.7. Beispiel für eine JSON-Antwort

Die JSON-Antwort von unseren SpringControllerhat das folgende Format:

{
    "ipAddress":"your-ip-address",
    "city":"your-city",
    "latitude":"your-latitude",
    "longitude":"your-longitude"
}

4.8. Anzeigen des Standorts in Google Maps

Um den Standort in Google Maps anzuzeigen, müssen Sie die Google Maps-API in Ihren HTML-Code aufnehmen:

Sie können einen API-Schlüssel für Google Maps über die Google Developer Console erhalten.

Sie müssen auch ein HTML<div>-Tag definieren, um das Kartenbild zu enthalten:

Mit der folgenden JavaScript-Funktion können Sie die Koordinaten in Google Maps anzeigen:

function showLocationOnMap (location) {
    var map;
    map = new google.maps.Map(document.getElementById('map'), {
      center: {
        lat: Number(location.latitude),
        lng: Number(location.longitude)},
        zoom: 15
    });
    var marker = new google.maps.Marker({
      position: {
        lat: Number(location.latitude),
        lng: Number(location.longitude)},
        map: map,
        title:
          "Public IP:"+location.ipAddress
            +" @ "+location.city
    });
}

Öffnen Sie nach dem Starten der Webanwendung die URL für die Kartenseite:

http://localhost:8080/spring-mvc-xml/GeoIpTest.jsp

Die aktuelle öffentliche IP-Adresse für Ihre Verbindung wird in das Textfeld geladen:

image

Beachten Sie, dass sowohl GeoIP2 als auch ipify sowohl IPv4-Adressen als auch IPv6-Adressen unterstützen.

Wenn Sie das Formular abschicken, wird der JSON-Antworttext angezeigt, einschließlich der Stadt, des Breiten- und Längengrads, die Ihrer öffentlichen IP-Adresse entsprechen. Darunter wird eine Google Map angezeigt, die auf Ihren Standort verweist:

image

5. Fazit

In diesem Tutorial haben wir die Verwendung der MaxMind GeoIP2 Java API und der kostenlosen MaxMind GeoLite2 City-Datenbank mit einem JUnit-Test überprüft.

Dann haben wir eine Spring MVCController und einen Service erstellt, um die Geolokalisierungsdaten (Stadt, Breite, Länge) von einer IP-Adresse zu erhalten.

Schließlich haben wir ein HTML / JavaScript-Frontend erstellt, um zu demonstrieren, wie diese Funktion verwendet werden kann, um den Standort eines Nutzers in Google Maps anzuzeigen.

Dieses Produkt enthält von MaxMind erstellte GeoLite2-Daten, verfügbar abhttp://www.maxmind.com.

Der Code für dieses Tutorial befindet sich aufGithub site.