Geolokalisierung nach IP in Java

1. Einleitung

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.

Wir werden dies auch mit einer einfachen Spring MVC Web-Demo-Anwendung in Aktion sehen.

2. Erste Schritte

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

2.1. Maven-Abhängigkeit

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

 com.maxmind.geoip2 geoip2 2.8.0 

Die neueste Version der API finden Sie in Maven Central.

2.2. Herunterladen der Datenbank

Als Nächstes müssen Sie die GeoLite2-Datenbank herunterladen. Für dieses Tutorial verwenden wir die binäre komprimierte Version der GeoLite2 City-Datenbank.

Nachdem Sie das Archiv entpackt haben, haben Sie eine Datei mit dem Namen GeoLite2-City.mmdb . Dies ist eine Datenbank mit IP-zu-Standort-Zuordnungen 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 einen DatabaseReader , um die Datenbank abzufragen:

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

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

CityResponse response = dbReader.city(ipAddress);

Das CityResponse- Objekt enthält mehrere andere Informationen als nur den Namen der Stadt. Hier ist ein Beispiel für einen JUnit-Test, der zeigt, wie die Datenbank geöffnet, die Stadtinformationen für eine IP-Adresse abgerufen und diese Informationen aus der CityResponse extrahiert werden :

@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 beginnen mit einer grundlegenden Spring Web MVC-Anwendung. Dann schreiben wir einen Controller , der 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 unseren Controller senden und das Ergebnis in Google Maps anzeigen.

4.1. Die Antwortentitätsklasse

Beginnen wir mit der Definition der Klasse, die die Geolocation-Antwort 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 Geolocation-Daten 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 auf den Controller für Spring MVC, der 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 zum Aufrufen unseres Spring Controllers hinzu, 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 jQuery und der JavaScript-API von ipify.org mit der öffentlichen IP-Adresse des Benutzers vor:

   $(document).ready (function () { $.get( "//api.ipify.org?format=json", function( data ) { $("#ip").val(data.ip) ; }); ... 

4.6. Senden der Ajax POST-Anfrage

Wenn das Formular gesendet wird, senden wir eine Ajax-POST-Anforderung an den Spring Controller , 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 unserem Spring Controller hat 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 einen HTML-Code definieren Tag, 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:

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

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

Note that both GeoIP2 and ipify support IPv4 addresses as well as IPv6 addresses.

When you submit the form, you'll see the JSON response text, including the city, latitude, and longitude corresponding to your public IP Address, and below that, you'll see a Google Map pointing to your location:

5. Conclusion

In this tutorial, we reviewed the usage of the MaxMind GeoIP2 Java API and free MaxMind GeoLite2 City database using a JUnit test.

Then we built a Spring MVC Controller and service to obtain the geolocation data (city, latitude, longitude) from an IP address.

Finally, we built an HTML/JavaScript front end to demonstrate how this feature can be used to display a user's location on Google Maps.

This product includes GeoLite2 data created by MaxMind, available from //www.maxmind.com.

Den Code für dieses Tutorial finden Sie auf der Github-Website.