Geolocalizzazione tramite IP in Java

1. Introduzione

In questo articolo, esploreremo come ottenere i dati sulla posizione geografica da un indirizzo IP utilizzando l'API Java MaxMind GeoIP2 con il database GeoLite2 gratuito.

Lo vedremo anche in azione utilizzando una semplice applicazione demo Web Spring MVC.

2. Introduzione

Per iniziare, dovrai scaricare l'API GeoIP2 e il database GeoLite2 da MaxMind.

2.1. Dipendenza da Maven

Per includere l'API MaxMind GeoIP2 nel tuo progetto Maven, aggiungi quanto segue al file pom.xml :

 com.maxmind.geoip2 geoip2 2.8.0 

Per ottenere l'ultima versione dell'API, puoi trovarla su Maven Central.

2.2. Download del database

Successivamente, dovrai scaricare il database GeoLite2. Per questo tutorial, stiamo usando la versione gzip binaria del database GeoLite2 City.

Dopo aver decompresso l'archivio, avrai un file denominato GeoLite2-City.mmdb . Si tratta di un database di mappature da IP a posizione nel formato binario proprietario MaxMind.

3. Utilizzo dell'API Java GeoIP2

Usiamo l'API Java GeoIP2 per recuperare i dati sulla posizione per un dato indirizzo IP dal database. Per prima cosa, creiamo un DatabaseReader per interrogare il database:

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

Successivamente, utilizziamo il metodo city ​​() per ottenere i dati della città per un indirizzo IP:

CityResponse response = dbReader.city(ipAddress);

L' oggetto CityResponse contiene diverse informazioni oltre al nome della città. Ecco un esempio di test JUnit che mostra come aprire il database, recuperare le informazioni sulla città per un indirizzo IP ed estrarre queste informazioni da CityResponse :

@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. Utilizzo di GeoIP in un'applicazione Web

Diamo un'occhiata a un'applicazione Web di esempio che recupera i dati di geolocalizzazione dall'indirizzo IP pubblico di un utente e visualizza la posizione su una mappa.

Inizieremo con un'applicazione Spring Web MVC di base. Quindi scriveremo un controller che accetta un indirizzo IP in una richiesta POST e restituisce una risposta JSON contenente città, latitudine e longitudine dedotte dall'API GeoIP2.

Infine, scriveremo un po 'di HTML e JavaScript che caricherà l'indirizzo IP pubblico dell'utente nel modulo, invieremo una richiesta Ajax POST al nostro controller e visualizzeremo il risultato in Google Maps.

4.1. La classe di entità di risposta

Iniziamo definendo la classe che conterrà la risposta di geolocalizzazione:

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

4.2. La classe di servizio

Ora scriviamo la classe di servizio che recupera i dati di geolocalizzazione utilizzando l'API Java GeoIP2 e il database GeoLite2:

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. Lo Spring Controller

Diamo un'occhiata al Controller per Spring MVC che invia il parametro di richiesta "ipAddress" alla nostra classe di servizio per ottenere i dati di risposta della geolocalizzazione:

@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. Il modulo HTML

Aggiungiamo il codice front-end per chiamare il nostro Spring Controller, iniziando con un modulo HTML contenente l'indirizzo IP:

     ... 

4.5. Caricamento dell'indirizzo IP pubblico sul client

Ora precompiliamo il campo di testo "ipAddress" con l'indirizzo IP pubblico dell'utente, utilizzando jQuery e l'API JavaScript ipify.org:

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

4.6. Invio della richiesta POST Ajax

Quando il modulo viene inviato, effettueremo una richiesta POST Ajax allo Spring Controller per recuperare la risposta JSON con i dati di geolocalizzazione:

$( "#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. Risposta JSON di esempio

La risposta JSON dal nostro Spring Controller avrà il seguente formato:

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

4.8. Visualizzazione della posizione su Google Maps

Per visualizzare la posizione su Google Maps, dovrai includere l'API di Google Maps nel tuo codice HTML:

Puoi ottenere una chiave API per Google Maps utilizzando la Google Developer Console.

Dovrai anche definire un HTML tag per contenere l'immagine della mappa:

Puoi utilizzare la seguente funzione JavaScript per visualizzare le coordinate su Google Maps:

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 }); }

Dopo aver avviato l'applicazione web, apri l'URL della pagina della mappa:

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

Vedrai l'attuale indirizzo IP pubblico per la tua connessione caricato nella casella di testo:

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.

Il codice per questo tutorial può essere trovato sul sito Github.