项目需要,要获得客户访问的国家。数据库用的是 http://software77.net/geo-ip/ 的数据库。这个数据库比较简单,免费,能够根据ipv4转换成国家,但是详细的地区没有。但是对于需求来说够了。
下载之后,去掉注释的部分和双引号,保存成.csv。
改好的在http://www.kuaipan.cn/file/id_107671437086556161.htm下载
代码如下。
public class IPtoCountry {
private static final Logger logger = LoggerFactory.getLogger(IPtoCountry.class);
private static final String UNKNOWN = "Unknown";
private static TreeMap<Long, String> map = new TreeMap<Long, String>();
/需要先调用一次,来初始化
public static void initialize() throws Exception {
logger.info("Start to read ip-to-country data");
try {
/// 读入,可以用其他方法读入, 比如FileInputStream
/// 这里用的是class.getResourceAsStream
InputStream in = ConnectionManager.class.getResourceAsStream("/db/IpToCountry.csv");
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String s = br.readLine();
while (s != null) {
insert(s);
s = br.readLine();
}
} catch (Exception e) {
logger.error("read iptocountry", e);
logger.error("Cannot read iptocontry db/IpToCountry.csv from " + System.getProperty("user.dir"));
}
logger.info("End to read ip-to-country data. " + map.size() + " records read.");
}
/将从数据库文件读出来的记录,插入一个TreeMap中。使用TreeMap是因为很方便查找
private static void insert(String s) {
String[] items = s.split(",");
if (items.length != 7) {
System.err.println(s);
return;
}
try {
///结束的ip
String end = items[1];
///国家
String country = items[6];
map.put(Long.valueOf(end), country);
} catch(Exception e) {
logger.error("Exception", e);
}
}
/ 根据ip转换成的long,在数据库中查找这个long坐落在那个区间范围内。
/ 如果找到了,返回国家。否则返回unknown
public static String get(long longIP) {
///这里用了ceilingEntry方法,得到TreeMap中的比所给定ip大的最小的项,该项即为所求
Entry<Long, String> e = map.ceilingEntry(longIP);
if (e == null) {
return UNKNOWN;
}
return e.getValue();
}
/ 按照ip数据库中注释的说明,将4位的ip转换成一个long
public static long getDeviceIPAsLong(String deviceIP) {
if (deviceIP == null || deviceIP.isEmpty()) {
return -1;
}
try {
String[] digits = deviceIP.split("\\.");
if (digits.length != 4) {
return -1;
}
long l3 = Long.parseLong(digits[3]);
long l2 = Long.parseLong(digits[2]);
long l1 = Long.parseLong(digits[1]);
long l0 = Long.parseLong(digits[0]);
return l3 + 256 * l2 + 256 * 256 * l1 + 256 * 256 * 256 * l0;
} catch(Exception e) {
return -1;
}
}
public static String get(String deviceip) {
long l = getDeviceIPAsLong(deviceip);
if (l == -1) {
return UNKNOWN;
}
return get(l);
}
}