Localização geográfica por IP em Java
1. Introdução
Neste artigo, exploraremos como obter dados de localização geográfica a partir de um endereço IP usando a API Java MaxMind GeoIP2 com o banco de dados GeoLite2 gratuito.
Também veremos isso em ação usando um aplicativo de demonstração da Web Spring MVC simples.
2. Começando
Para começar, você precisará baixar a API GeoIP2 e o banco de dados GeoLite2 da MaxMind.
2.1. Dependência do Maven
Para incluir a API MaxMind GeoIP2 em seu projeto Maven, adicione o seguinte ao arquivopom.xml:
com.maxmind.geoip2
geoip2
2.8.0
Para obter a versão mais recente da API, você pode encontrá-la emMaven Central.
2.2. Baixando o banco de dados
Em seguida, você precisará baixar oGeoLite2 database. Para este tutorial, estamos usando a versão binária compactada em gz do banco de dados GeoLite2 City.
Depois de descompactar o arquivo, você terá um arquivo chamadoGeoLite2-City.mmdb. Este é um banco de dados de mapeamentos de IP para local no formato binário proprietário MaxMind.
3. Usando a API GeoIP2 Java
Vamos usar a API GeoIP2 Java para buscar dados de localização para um determinado endereço IP do banco de dados. Primeiro, vamos criar umDatabaseReader para consultar o banco de dados:
File database = new File(dbLocation);
DatabaseReader dbReader = new DatabaseReader.Builder(database).build();
A seguir, vamos usar o métodocity() para obter os dados da cidade para um endereço IP:
CityResponse response = dbReader.city(ipAddress);
O objetoCityResponse contém várias informações além do nome da cidade. Aqui está um exemplo de teste JUnit mostrando como abrir o banco de dados, buscar as informações da cidade para um endereço IP e extrair essas informações doCityResponse:
@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. Usando GeoIP em um aplicativo da Web
Vejamos um exemplo de aplicativo da web que busca dados de geolocalização do endereço IP público de um usuário e exibe a localização em um mapa.
Começaremos combasic Spring Web MVC Application. Em seguida, escreveremos umController que aceita um endereço IP em uma solicitação POST e retorna uma resposta JSON contendo cidade, latitude e longitude deduzidas da API GeoIP2.
Por fim, escreveremos HTML e JavaScript que carregarão o endereço IP público do usuário no formulário, enviaremos uma solicitação Ajax POST para nossoController e exibiremos o resultado no Google Maps
4.1. A Classe de Entidade de Resposta
Vamos começar definindo a classe que conterá a resposta da geolocalização:
public class GeoIP {
private String ipAddress;
private String city;
private String latitude;
private String longitude;
// constructors, getters and setters...
}
4.2. A classe de serviço
Agora vamos escrever a classe de serviço que busca os dados de geolocalização usando a API GeoIP2 Java e o banco de dados 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. O controlador de mola
Vamos dar uma olhada emController para Spring MVC, que envia o parâmetro de solicitação “ipAddress” para nossa classe de serviço para obter os dados de resposta de geolocalização:
@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. O Formulário HTML
Vamos adicionar o código de front-end para chamar nosso SpringController, começando com um formulário HTML contendo o endereço IP:
...
4.5. Carregando o endereço IP público no cliente
Agora vamos preencher previamente o campo de texto “ipAddress” com o endereço IP público do usuário, usando jQuery e a API JavaScriptipify.org:
4.6. Enviando a solicitação Ajax POST
Quando o formulário for enviado, faremos uma solicitação Ajax POST para SpringController para recuperar a resposta JSON com dados de geolocalização:
$( "#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. Resposta JSON de amostra
A resposta JSON de nosso SpringController terá o seguinte formato:
{
"ipAddress":"your-ip-address",
"city":"your-city",
"latitude":"your-latitude",
"longitude":"your-longitude"
}
4.8. Exibindo a localização no Google Maps
Para exibir o local no Google Maps, você precisará incluir a API do Google Maps em seu código HTML:
Você pode obter uma chave de API para o Google Maps usando o Google Developer Console.
Você também precisará definir uma tag HTML<div> para conter a imagem do mapa:
Você pode usar a seguinte função JavaScript para exibir as coordenadas no 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
});
}
Após iniciar o aplicativo Web, abra o URL da página do mapa:
http://localhost:8080/spring-mvc-xml/GeoIpTest.jsp
Você verá o endereço IP público atual da sua conexão carregado na caixa de texto:
Observe que o GeoIP2 e o ipify suportam endereços IPv4 e endereços IPv6.
Ao enviar o formulário, você verá o texto de resposta JSON, incluindo a cidade, latitude e longitude correspondentes ao seu endereço IP público e, abaixo disso, você verá um mapa do Google apontando para sua localização:
5. Conclusão
Neste tutorial, revisamos o uso da API Java MaxMind GeoIP2 e do banco de dados gratuito MaxMind GeoLite2 City usando um teste JUnit.
Em seguida, construímos um Spring MVCControllere serviço para obter os dados de geolocalização (cidade, latitude, longitude) de um endereço IP.
Por fim, construímos um front-end HTML / JavaScript para demonstrar como esse recurso pode ser usado para exibir a localização de um usuário no Google Maps.
Este produto inclui dados GeoLite2 criados por MaxMind, disponíveis emhttp://www.maxmind.com.
O código para este tutorial pode ser encontrado emGithub site.