Géolocalisation par IP en Java

1. Introduction

Dans cet article, nous allons explorer comment obtenir des données de localisation géographique à partir d'une adresse IP en utilisant l'API Java MaxMind GeoIP2 avec la base de données gratuite GeoLite2.

Nous verrons également cela en action à l'aide d'une simple application de démonstration Web Spring MVC.

2. Premiers pas

Pour commencer, vous devrez télécharger l'API GeoIP2 et la base de données GeoLite2 à partir de MaxMind.

2.1. Dépendance de Maven

Pour inclure l'API MaxMind GeoIP2 dans votre projet Maven, ajoutez ce qui suit au fichier pom.xml :

 com.maxmind.geoip2 geoip2 2.8.0 

Pour obtenir la dernière version de l'API, vous pouvez la trouver sur Maven Central.

2.2. Téléchargement de la base de données

Ensuite, vous devrez télécharger la base de données GeoLite2. Pour ce tutoriel, nous utilisons la version binaire gzippée de la base de données GeoLite2 City.

Après avoir déballé l'archive, vous aurez un fichier nommé GeoLite2-City.mmdb . Il s'agit d'une base de données de mappages IP-emplacement au format binaire propriétaire MaxMind.

3. Utilisation de l'API Java GeoIP2

Utilisons l'API Java GeoIP2 pour récupérer les données de localisation d'une adresse IP donnée dans la base de données. Tout d'abord, créons un DatabaseReader pour interroger la base de données:

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

Ensuite, utilisons la méthode city ​​() pour obtenir les données de ville pour une adresse IP:

CityResponse response = dbReader.city(ipAddress);

L' objet CityResponse contient plusieurs informations autres que le nom de la ville. Voici un exemple de test JUnit montrant comment ouvrir la base de données, récupérer les informations de ville pour une adresse IP et extraire ces informations de 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. Utilisation de GeoIP dans une application Web

Examinons un exemple d'application Web qui récupère les données de géolocalisation à partir de l'adresse IP publique d'un utilisateur et affiche l'emplacement sur une carte.

Nous allons commencer avec une application Spring Web MVC de base. Ensuite, nous écrirons un Controller qui accepte une adresse IP dans une requête POST et renvoie une réponse JSON contenant la ville, la latitude et la longitude déduites de l'API GeoIP2.

Enfin, nous écrirons du HTML et du JavaScript qui chargeront l'adresse IP publique de l'utilisateur dans le formulaire, soumettrons une requête Ajax POST à ​​notre contrôleur et afficherons le résultat dans Google Maps.

4.1. La classe d'entité de réponse

Commençons par définir la classe qui contiendra la réponse de géolocalisation:

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

4.2. La classe de service

Écrivons maintenant la classe de service qui récupère les données de géolocalisation à l'aide de l'API Java GeoIP2 et de la base de données 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. Le contrôleur de ressort

Jetons un coup d'œil au Controller for Spring MVC qui envoie le paramètre de requête «ipAddress» à notre classe de service pour obtenir les données de réponse de géolocalisation:

@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. Le formulaire HTML

Ajoutons le code frontal pour appeler notre Spring Controller, en commençant par un formulaire HTML contenant l'adresse IP:

     ... 

4.5. Chargement de l'adresse IP publique sur le client

Maintenant, pré-remplissons le champ de texte «ipAddress» avec l'adresse IP publique de l'utilisateur, à l'aide de jQuery et de l'API JavaScript ipify.org:

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

4.6. Soumettre la requête Ajax POST

Lorsque le formulaire est soumis, nous ferons une demande Ajax POST au Spring Controller pour récupérer la réponse JSON avec les données de géolocalisation:

$( "#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. Exemple de réponse JSON

La réponse JSON de notre Spring Controller aura le format suivant:

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

4.8. Affichage de la position sur Google Maps

Pour afficher la position sur Google Maps, vous devez inclure l'API Google Maps dans votre code HTML:

Vous pouvez obtenir une clé API pour Google Maps à l'aide de la Google Developer Console.

Vous devrez également définir un HTML balise pour contenir l'image de la carte:

Vous pouvez utiliser la fonction JavaScript suivante pour afficher les coordonnées sur 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 }); }

Après avoir démarré l'application Web, ouvrez l'URL de la page de carte:

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

Vous verrez l'adresse IP publique actuelle de votre connexion chargée dans la zone de texte:

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.

Le code de ce tutoriel se trouve sur le site Github.