最近在做一个互联网项目,不可避免和其他互联网项目一样,需要各种类似的功能。其中一个就是通过用户访问网站的IP地址显示当前用户所在地。在没有查阅资料之前,我第一个想到的是应该有这样的RESTFUL服务,可能会有免费的,也有可能会是收费的。后来查阅了相关资料和咨询了客服人员发现了一款相当不错的库:GEOIP。
中文官网:http://www.maxmind.com/zh/home?pkit_lang=zh
英文官网:http://www.maxmind.com/en/home
而且GeoIP也提供了如我之前猜测的功能:Web Services,具体可以看这里:http://dev.maxmind.com/geoip/legacy/web-services
这里我就把官方的实例搬过来吧,Web Services :
首先来个Java 版本:
import java.net.MalformedURLException; import java.net.URL; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class OmniReader { public static void main(String[] args) throws Exception { String license_key = "YOUR_LICENSE_KEY"; String ip_address = "24.24.24.24"; String url_str = "http://geoip.maxmind.com/e?l=" + license_key + "&i=" + ip_address; URL url = new URL(url_str); BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); String inLine; while ((inLine = in.readLine()) != null) { // Alternatively use a CSV parser here. Pattern p = Pattern.compile("\"([^\"]*)\"|(?<=,|^)([^,]*)(?:,|$)"); Matcher m = p.matcher(inLine); ArrayList fields = new ArrayList(); String f; while (m.find()) { f = m.group(1); if (f!=null) { fields.add(f); } else { fields.add(m.group(2)); } } String countrycode = fields.get(0); String countryname = fields.get(1); String regioncode = fields.get(2); String regionname = fields.get(3); String city = fields.get(4); String lat = fields.get(5); String lon = fields.get(6); String metrocode = fields.get(7); String areacode = fields.get(8); String timezone = fields.get(9); String continent = fields.get(10); String postalcode = fields.get(11); String isp = fields.get(12); String org = fields.get(13); String domain = fields.get(14); String asnum = fields.get(15); String netspeed = fields.get(16); String usertype = fields.get(17); String accuracyradius = fields.get(18); String countryconf = fields.get(19); String cityconf = fields.get(20); String regionconf = fields.get(21); String postalconf = fields.get(22); String error = fields.get(23); } in.close(); } }
private string GetMaxMindOmniData(string IP) { System.Uri objUrl = new System.Uri("http://geoip.maxmind.com/e?l=YOUR_LICENSE_KEY&i=" + IP); System.Net.WebRequest objWebReq; System.Net.WebResponse objResp; System.IO.StreamReader sReader; string strReturn = string.Empty; try { objWebReq = System.Net.WebRequest.Create(objUrl); objResp = objWebReq.GetResponse(); sReader = new System.IO.StreamReader(objResp.GetResponseStream()); strReturn = sReader.ReadToEnd(); sReader.Close(); objResp.Close(); } catch (Exception ex) { } finally { objWebReq = null; } return strReturn; }
#!/usr/bin/env ruby require 'csv' require 'net/http' require 'open-uri' require 'optparse' require 'uri' fields = [:country_code, :country_name, :region_code, :region_name, :city_name, :latitude, :longitude, :metro_code, :area_code, :time_zone, :continent_code, :postal_code, :isp_name, :organization_name, :domain, :as_number, :netspeed, :user_type, :accuracy_radius, :country_confidence, :city_confidence, :region_confidence, :postal_confidence, :error] options = { :license => "YOUR_LICENSE_KEY", :ip => "24.24.24.24" } OptionParser.new { |opts| opts.banner = "Usage: omni-geoip-ws.rb [options]" opts.on("-l", "--license LICENSE", "MaxMind license key") do |l| options[:license] = l end opts.on("-i", "--ip IPADDRESS", "IP address to look up") do |i| options[:ip] = i end }.parse! uri = URI::HTTP.build(:scheme => 'http', :host => 'geoip.maxmind.com', :path => '/e', :query => URI.encode_www_form(:l => options[:license], :i => options[:ip])) response = Net::HTTP.get_response(uri) unless response.is_a?(Net::HTTPSuccess) abort "Request failed with status #{response.code}" end omni = Hash[fields.zip(response.body.encode('utf-8', 'iso-8859-1').parse_csv)] if omni[:error] abort "MaxMind returned an error code for the request: #{omni[:error]}" else puts puts "MaxMind Omni data for #{options[:ip]}"; puts omni.each { |key, val| printf " %-20s %s\n", key, val } puts end
#!/usr/bin/env perl use strict; use warnings; use Encode qw( decode ); use Getopt::Long; use LWP::UserAgent; use Text::CSV_XS; use URI; use URI::QueryParam; my @fields = qw( country_code country_name region_code region_name city_name latitude longitude metro_code area_code time_zone continent_code postal_code isp_name organization_name domain as_number netspeed user_type accuracy_radius country_confidence city_confidence region_confidence postal_confidence error ); my $license_key = 'YOUR_LICENSE_KEY'; my $ip_address = '24.24.24.24'; GetOptions( 'license:s' => \$license_key, 'ip:s' => \$ip_address, ); my $uri = URI->new('http://geoip.maxmind.com/e'); $uri->query_param( l => $license_key ); $uri->query_param( i => $ip_address ); my $ua = LWP::UserAgent->new( timeout => 5 ); my $response = $ua->get($uri); die 'Request failed with status ' . $response->code() unless $response->is_success(); my $csv = Text::CSV_XS->new( { binary => 1 } ); $csv->parse( decode( 'ISO-8859-1', $response->content() ) ); my %omni; @omni{@fields} = $csv->fields(); binmode STDOUT, ':encoding(UTF-8)'; if ( defined $omni{error} && length $omni{error} ) { die "MaxMind returned an error code for the request: $omni{error}\n"; } else { print "\nMaxMind Omni data for $ip_address\n\n"; for my $field (@fields) { print sprintf( " %-20s %s\n", $field, $omni{$field} ); } print "\n"; }
首先在项目中需要添加库文件:GeoLiteCity,然后就可以利用这个文件得到城市和国家信息了。项目中如何获取到用户访问的IP地址就不用我说了吧,做过Web开发的人应该都知道。Request里面获取。Java代码:
public class GeoBusiness { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { // TODO Auto-generated method stub System.out.println(getLocationByIp("220.181.111.147").getCity()); System.out.println(getLocationByIp("220.181.111.147").getCountryName()); } public static Location getLocationByIp(String ipaddr) throws IOException { String sep = System.getProperty("file.separator"); String dir = Play.configuration.getProperty("geoip.datdir"); String dbfile = dir + sep + "GeoLiteCity.dat"; LookupService cl = new LookupService(dbfile, LookupService.GEOIP_MEMORY_CACHE); Location location = cl.getLocation(ipaddr); cl.close(); return location; } }