Spring MVC – find location using IP Address (jQuery + Google Map)
In this tutorial, we show you how to find a location using an IP address, with the following technologies :
- Spring MVC frameworks.
- jQuery (Ajax Request).
- GeoLite database.
- Google Map.
Review the tutorial’s flows
- A page with a text input and button.
- Type an IP address, and clicks on the button.
- jQuery fires an Ajax request to Spring Controller.
- Spring controller process and return back a json string.
- jQuery process the returned json and display the location on Google Map.
1. Project Directory
Review the final project directory structure, a standard Maven project.
Note
Download the free GeoLite free Databases – GeoLiteCity.dat, and put it into the
Download the free GeoLite free Databases – GeoLiteCity.dat, and put it into the
resources
folder.
2. Project Dependencies
Declares Spring frameworks, Jackson and geoip-api dependencies.
pom.xml
//...
<properties>
<spring.version>3.2.2.RELEASE</spring.version>
<maxmind.geoip.version>1.2.10</maxmind.geoip.version>
<jackson.version>1.9.10</jackson.version>
</properties>
<dependencies>
<!-- Spring Core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- need this for @Configuration -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- ip to server location -->
<dependency>
<groupId>com.maxmind.geoip</groupId>
<artifactId>geoip-api</artifactId>
<version>${maxmind.geoip.version}</version>
</dependency>
<!-- Jackson -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
//...
3. Spring MVC + GeoLite
Get the location with GeoLite database.
ServerLocationBo.java
package com.mkyong.web.location;
public interface ServerLocationBo {
ServerLocation getLocation(String ipAddress);
}
ServerLocationBoImpl.java
package com.mkyong.web.location;
import java.io.IOException;
import java.net.URL;
import org.springframework.stereotype.Component;
import com.maxmind.geoip.Location;
import com.maxmind.geoip.LookupService;
import com.maxmind.geoip.regionName;
@Component
public class ServerLocationBoImpl implements ServerLocationBo {
@Override
public ServerLocation getLocation(String ipAddress) {
String dataFile = "location/GeoLiteCity.dat";
return getLocation(ipAddress, dataFile);
}
private ServerLocation getLocation(String ipAddress, String locationDataFile) {
ServerLocation serverLocation = null;
URL url = getClass().getClassLoader().getResource(locationDataFile);
if (url == null) {
System.err.println("location database is not found - "
+ locationDataFile);
} else {
try {
serverLocation = new ServerLocation();
LookupService lookup = new LookupService(url.getPath(),
LookupService.GEOIP_MEMORY_CACHE);
Location locationServices = lookup.getLocation(ipAddress);
serverLocation.setCountryCode(locationServices.countryCode);
serverLocation.setCountryName(locationServices.countryName);
serverLocation.setRegion(locationServices.region);
serverLocation.setRegionName(regionName.regionNameByCode(
locationServices.countryCode, locationServices.region));
serverLocation.setCity(locationServices.city);
serverLocation.setPostalCode(locationServices.postalCode);
serverLocation.setLatitude(
String.valueOf(locationServices.latitude));
serverLocation.setLongitude(
String.valueOf(locationServices.longitude));
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
return serverLocation;
}
}
ServerLocation.java
package com.mkyong.web.location;
public class ServerLocation {
private String countryCode;
private String countryName;
private String region;
private String regionName;
private String city;
private String postalCode;
private String latitude;
private String longitude;
//getter and setter methods
}
Spring controller, convert the ServerLocation
with Jackson
library, and return back a json string.
MapController.java
package com.mkyong.web.controller;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.mkyong.web.location.ServerLocation;
import com.mkyong.web.location.ServerLocationBo;
@Controller
public class MapController {
@Autowired
ServerLocationBo serverLocationBo;
@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView getPages() {
ModelAndView model = new ModelAndView("map");
return model;
}
//return back json string
@RequestMapping(value = "/getLocationByIpAddress", method = RequestMethod.GET)
public @ResponseBody
String getDomainInJsonFormat(@RequestParam String ipAddress) {
ObjectMapper mapper = new ObjectMapper();
ServerLocation location = serverLocationBo.getLocation(ipAddress);
String result = "";
try {
result = mapper.writeValueAsString(location);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
4. JSP + jQuery + Google Map
When the search button is clicked, jQuery fire an Ajax request, process the data and update the Google Map.
map.jsp
<html>
<head>
<script src="http://maps.google.com/maps/api/js?sensor=true"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<h2>Spring MVC + jQuery + Google Map</h2>
<div>
<input type="text" placeholder="0.0.0.0" id="w-input-search" value="">
<span>
<button id="w-button-search" type="button">Search</button>
</span>
</div>
<script>
$(document).ready(function() {
$("#w-button-search").click(function() {
$.getJSON("${pageContext.request.contextPath}/getLocationByIpAddress",
{
ipAddress : $('#w-input-search').val()
},
function(data) {
var data = JSON.stringify(data);
var json = JSON.parse(data);
showMap(json["latitude"],json["longitude"])
$("#result").html(data)
})
.done(function() {
})
.fail(function() {
})
.complete(function() {
});
});
var map;
function showMap(latitude,longitude) {
var googleLatandLong = new google.maps.LatLng(latitude,longitude);
var mapOptions = {
zoom: 5,
center: googleLatandLong,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var mapDiv = document.getElementById("map");
map = new google.maps.Map(mapDiv, mapOptions);
var title = "Server Location";
addMarker(map, googleLatandLong, title, "");
}
function addMarker(map, latlong, title, content) {
var markerOptions = {
position: latlong,
map: map,
title: title,
clickable: true
};
var marker = new google.maps.Marker(markerOptions);
}
});
</script>
<br/>
<div id="result"></div>
<br/>
<div style="width:600px;height:400px" id="map"></div>
</body>
</html>
5. Demo
IP Address : 74.125.135.102
IP Address : 183.81.166.110
Download Source Code
Download it – SpringMvc-jQuery-GoogleMap (18 KB)
Thank you so much for sharing. I have downloaded, built and ran the project but getting following error:
Oct 11, 2013 12:15:49 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 4262 ms
location database is not found – location/GeoLiteCity.dat
Am I missing anything? Thanks a lot!
we have fields in database address1,postcode,city,state etc based on that we need to display google map indicators around we have 60 records in database.can you guide us pleas.once i add the records in database auto matic generate the indicators in my web applicatioon thank you.
This is very informative post.
by using this post we can learn many thing.
thanks
Hi a download the example code and work perfectly, next to i copy the code to my other project and the consolde displays the following error
GRAVE: Servlet.service() for servlet [dispatcher] in context with path [/project] threw ex
ception [Request processing failed; nested exception is java.lang.ArrayIndexOutOfBoundsExc
eption: 94012680] with root cause
java.lang.ArrayIndexOutOfBoundsException: 94012680
at com.maxmind.geoip.LookupService.seekCountry(LookupService.java:1135)
at com.maxmind.geoip.LookupService.getLocation(LookupService.java:872)
at com.maxmind.geoip.LookupService.getLocation(LookupService.java:610)
at com.maxmind.geoip.LookupService.getLocation(LookupService.java:624)
at com.litekey.mytv.persistence.core.impl.ServerLocationBoImpl.getLocation(ServerL
ocationBoImpl.java:41)
at com.litekey.mytv.persistence.core.impl.ServerLocationBoImpl.getLocation(ServerL
ocationBoImpl.java:21)
at com.litekey.mytv.web.controllers.HomeController.getDomainInJsonFormat(HomeContr
oller.java:336)
please someone can help me?
how can i store it into tables?
Great article indeed. The only thing missing is a reverse geocoding implementation to pull the closest street address associated with the longitude and latitude data pulled from the maxmind db. Could be fun. There’s an implemetation at http://geoipinfo.org that does just that (on the interactive map tab)
me downloaded the GeoLiteCity.dat form the site and include it in path but it is throwing the following exception what it means how to resolve this please help
com.maxmind.db.InvalidDatabaseException: Could not find a MaxMind DB metadata marker in this file (GeoLiteCity.dat). Is this a valid MaxMind DB file?
at com.maxmind.db.Reader.findMetadataStart(Reader.java:231)
are you downloaded the file GeoLiteCity.dat?
Any insight how to do this if I wanted to show multiple IP addresses on the map at the same time?
Useful article! Thank you, Mauro
Good work thanks.
Ddownloaded the missing “GeoLiteCity.dat” file separately from “http://dev.maxmind.com/geoip/legacy/geolite/”. Unzipped it to “src/main/resources/location”. Things are seem to be working now. But map is displaying location a few miles off the target location. Hmmm…
Have you seeing this before?
The free “GeoLiteCity.dat” is not guarantee a 100% exact location (read the maxmind’s document), the “few miles off” is still acceptable 🙂
Found the reason for the error. Zip file “SpringMvc-jQuery-GoogleMap.zip” would not work as is because it has a missing file “GeoLiteCity.dat”. Directory “src/main/resources/location” is empty. That’s why getting above error when run the project.
Is there a working version of this project?
Sorry, I excluded the “GeoLiteCity.dat” file, it’s too big to include in the download source. You need to download it manually.
Hi MkYong,
Can you please share the url from where I need to download this file.
It’s my bad. You mentioned in the note that the file should be downloaded separately and I missed it. I found the file by googling and then saw your note. My mistake, sorry.
Again, thank you so much for sharing the project!
Thanks mkyong.
can we show locations dynamically also???means if we dont give hardcode value and just access through a function???/
What you mean by show “location dynamically”? To display the location on Google Map, you need to get “latitude” and “longitude”.
Cool!
you are always great..:)