您的位置:首页 > 编程语言 > Java开发

Java - 通过IP地址获取用户所在地

2013-05-19 08:28 609 查看
最近在做一个互联网项目,不可避免和其他互联网项目一样,需要各种类似的功能。其中一个就是通过用户访问网站的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;
}
}


更详细的功能比如获取省,经纬度可以参考我最前面给出的网址。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: