最近在做一个互联网项目,不可避免和其他互联网项目一样,需要各种类似的功能。其中一个就是通过用户访问网站的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();
- }
- }
C#版本:
- 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;
- }
Ruby版本:
- #!/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
最后再来个Perl版本吧:
- #!/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";
- }
以上都是基于Web Services的,这里我再写个使用本地库的实例,而项目中也使用的是本地库。
首先在项目中需要添加库文件: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;
- }
- }
更详细的功能比如获取省,经纬度可以参考我最前面给出的网址。