Геолокация по IP в Java

Геолокация по IP в Java

1. Вступление

В этой статье мы рассмотрим, как получить данные о географическом местоположении с IP-адреса с помощью Java API MaxMind GeoIP2 с бесплатной базой данных GeoLite2.

Мы также увидим это в действии, используя простое демонстрационное веб-приложение Spring MVC.

2. Начиная

Для начала вам необходимо загрузить GeoIP2 API и базу данных GeoLite2 с MaxMind.

2.1. Maven Dependency

Чтобы включить API MaxMind GeoIP2 в свой проект Maven, добавьте в файлpom.xml следующее:


    com.maxmind.geoip2
    geoip2
    2.8.0

Чтобы получить последнюю версию API, вы можете найти ее наMaven Central.

2.2. Скачивание базы данных

Затем вам нужно скачатьGeoLite2 database. Для этого урока мы используем бинарную версию базы данных GeoLite2 City в сжатом виде.

После распаковки архива у вас будет файл с именемGeoLite2-City.mmdb. Это база данных сопоставлений IP-адресов в собственном двоичном формате MaxMind.

3. Использование API Java GeoIP2

Давайте воспользуемся Java API GeoIP2, чтобы получить данные о местоположении для данного IP-адреса из базы данных. Во-первых, давайте создадимDatabaseReader для запроса базы данных:

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

Затем давайте воспользуемся методомcity() для получения данных о городе для IP-адреса:

CityResponse response = dbReader.city(ipAddress);

ОбъектCityResponse содержит несколько частей информации, кроме названия города. Вот пример теста JUnit, показывающий, как открыть базу данных, получить информацию о городе для IP-адреса и извлечь эту информацию из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. Использование GeoIP в веб-приложении

Рассмотрим пример веб-приложения, которое извлекает данные о геолокации с общедоступного IP-адреса пользователя и отображает его местоположение на карте.

Начнем сbasic Spring Web MVC Application. Затем мы напишемController, который принимает IP-адрес в запросе POST и возвращает ответ JSON, содержащий город, широту и долготу, полученные из API GeoIP2.

Наконец, мы напишем некоторые HTML и JavaScript, которые загрузят общедоступный IP-адрес пользователя в форму, отправят запрос Ajax POST в нашController и отобразят результат в Google Maps.

4.1. Класс сущности ответа

Начнем с определения класса, который будет содержать ответ геолокации:

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

4.2. Сервисный класс

Теперь давайте напишем сервисный класс, который извлекает данные геолокации с помощью Java API GeoIP2 и базы данных 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. Контроллер Spring

Давайте посмотрим наController для Spring MVC, который отправляет параметр запроса ipAddress в наш класс обслуживания, чтобы получить данные ответа геолокации:

@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. Форма HTML

Давайте добавим интерфейсный код для вызова нашей SpringController,, начиная с HTML-формы, содержащей IP-адрес:


    
...

4.5. Загрузка общедоступного IP-адреса на клиенте

Теперь давайте предварительно заполним текстовое поле ipAddress общедоступным IP-адресом пользователя с помощью jQuery и JavaScript APIipify.org:



4.6. Отправка запроса Ajax POST

Когда форма будет отправлена, мы сделаем запрос Ajax POST к SpringController, чтобы получить ответ JSON с данными геолокации:

$( "#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. Пример ответа JSON

Ответ JSON от нашего SpringController будет иметь следующий формат:

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

4.8. Отображение местоположения на Google Maps

Для отображения местоположения на Google Maps вам необходимо включить Google Maps API в свой HTML-код:

Вы можете получить ключ API для Карт Google с помощью консоли разработчика Google.

Вам также необходимо определить HTML-тег<div>, содержащий изображение карты:

Вы можете использовать следующую функцию JavaScript для отображения координат на Картах Google:

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

После запуска веб-приложения откройте URL-адрес страницы карты:

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

Вы увидите текущий публичный IP-адрес для вашего соединения, загруженный в текстовое поле:

image

Обратите внимание, что и GeoIP2, и ipify поддерживают адреса IPv4, а также адреса IPv6.

При отправке формы вы увидите текст ответа JSON, включая город, широту и долготу, соответствующие вашему общедоступному IP-адресу, а под ним вы увидите карту Google, указывающую на ваше местоположение:

image

5. Заключение

В этом руководстве мы рассмотрели использование Java API MaxMind GeoIP2 и бесплатную базу данных MaxMind GeoLite2 City с использованием теста JUnit.

Затем мы создали Spring MVCController и сервис для получения данных геолокации (город, широта, долгота) с IP-адреса.

Наконец, мы создали интерфейс HTML / JavaScript, чтобы продемонстрировать, как эту функцию можно использовать для отображения местоположения пользователя на Картах Google.

Этот продукт включает данные GeoLite2, созданные MaxMind, доступные сhttp://www.maxmind.com.

Код этого руководства можно найти наGithub site.