Ip2region的简单使用
需求中有些场景我们通过IP地址来统计活跃用户,所以就需要一些这样的工具类和方法,下面的是一个离线获取的方式,通过ip地址来获取ip的所在地。
为什么使用Ip2region,因为这个是一个离线库,查询的速度比较快,而且一直再持续维护中,精确度也比较高。
Ip2region打包下载
不想打包下载的,可以用这个地址
链接:https://pan.baidu.com/s/1exfawnaaCLSSILGLgFOTnw
提取码:dlf1
源码地址:
https://github.com/lionsoul2014/ip2region
如果想获取最新版的就下载源码打包出来。
工具类IpUtils
maven引入
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>1.7.2</version>
</dependency>
package com.swift.common.util;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.lionsoul.ip2region.xdb.Searcher;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Log4j2
public class IpUtils {
public static String getIpAddress(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (ip != null && ip.length() > 15) { // "***.***.***.***".length()
// = 15
if (ip.indexOf(",") > 0) {
ip = ip.substring(0, ip.indexOf(","));
}
}
return ip;
}
// private static DbSearcher searcher;
private static Searcher searcher;
static {
initIpSearcher();
}
/**
* 格式化地址
*
* @param val
* @param split
* @return
*/
private static String formatRegion(String val, String split) {
if ("0".equals(val)) {
return "";
}
return val + split;
}
private static void initIpSearcher() {
String dbPath = "";
//基于文件查询
// try {
// dbPath = IpUtils.class.getClassLoader().getResource("ip2region.xdb").getPath();
// searcher = Searcher.newWithFileOnly(dbPath);
// } catch (IOException e) {
// System.out.printf("failed to create searcher with `%s`: %s\n", dbPath, e);
// }
//基于内存查询
try {
dbPath = IpUtils.class.getClassLoader().getResource("ip2region.xdb").getPath();
byte[] cBuff = Searcher.loadContentFromFile(dbPath);
searcher = Searcher.newWithBuffer(cBuff);
} catch (Exception e) {
System.out.printf("failed to create content cached searcher: %s\n", e);
}
// InputStream inputStream = null;
// try {
// inputStream = IpUtils.class.getClassLoader().getResourceAsStream("ip2region.db");
// ByteArrayBuffer buff = new ByteArrayBuffer(10*1024*1024);
// int len = 0;
// byte[] data = new byte[2048];
// while((len = inputStream.read(data)) != -1){
// buff.append(data,0,len);
// }
// DbConfig config = new DbConfig();
// searcher = new DbSearcher(config, buff.buffer());
// buff.clear();
// } catch (Exception e) {
// e.printStackTrace();
// System.exit(-1);
// }
}
/**
* 获取IP归属地
*
* @param ip
* @return
*/
public static String getIpRegion(String ip) {
if (StringUtils.isNotBlank(ip)) {
if (ip.contains(",")) {
String[] split = ip.split(",");
ip = split[0];
}
}
return getIpRegion(ip, StringUtils.EMPTY);
}
/**
* 获取IP归属地
*
* @param ip
* @param split 地址拼接分隔符
* @return
*/
public static String getIpRegion(String ip, String split) {
try {
String region = searcher.search(ip);
if (StringUtils.isNotBlank(region)) {
String[] arr = StringUtils.split(region, '|');
if (arr.length > 3) {
return formatRegion(arr[0], split) + formatRegion(arr[2], split) + formatRegion(arr[3], StringUtils.EMPTY);
}
}
} catch (Exception e) {
log.warn("search ip region error", e);
}
// if(Util.isIpAddress(ip)){
// try {
// DataBlock dataBlock = searcher.memorySearch(ip);
// if(dataBlock != null){
// String[] arr = StringUtils.split(dataBlock.getRegion(),'|');
// if(arr.length > 3){
// StringBuilder buff = new StringBuilder();
// buff.append(formatRegion(arr[0],split)).append(formatRegion(arr[2],split)).append(formatRegion(arr[3],StringUtils.EMPTY));
// return buff.toString();
// }
// }
// return dataBlock.toString();
// } catch (IOException e) {
// log.warn("search ip region error",e);
// }
// }
return StringUtils.EMPTY;
}
public static String getPublicIp() {
String ip = "";
StringBuilder inputLine = new StringBuilder();
String read;
BufferedReader in = null;
try {
URL url = new URL("http://ip.chinaz.com");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), StandardCharsets.UTF_8));
while ((read = in.readLine()) != null) {
inputLine.append(read).append("\r\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Pattern p = Pattern.compile("\\<dd class\\=\"fz24\">(.*?)\\<\\/dd>");
Matcher m = p.matcher(inputLine.toString());
if (m.find()) {
ip = m.group(1);
}
log.info("获取的公网ip为[{}]", ip);
return ip;
}
public static void main(String[] args) {
System.out.println(getIpRegion("39.144.24.215"));
System.out.println(getIpRegion("153.35.52.159"));
}
}
获取出来的结果为
国家|区域|省份|城市|ISP
这些信息组成,
我们拿到结果后自行解析就行