老鬼的博客 来都来啦,那就随便看看吧~
ip地址转换归属地
发布于: 2024-06-24 更新于: 2024-06-24 分类于:  阅读次数: 

一:背景

1
2
3
如何根据ip地址获取省份和城市以及运营商等,其实高德和阿里都有相关的
接口文档,他们都是收费的,本文介绍一下使用ipRegion来进行转换,正确
率还算可以。

二:文档

三:相关方法

3.1 yml

1
2
3
# ip获取城市
ip2region:
path: D:\ip2region.xdb

3.2 IpUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package com.bluedeer.wechat.utils;

import org.apache.commons.lang3.ArrayUtils;
import org.lionsoul.ip2region.xdb.Searcher;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
* @desc ip工具类
* @author RenJie
* @date 2024-06-24
*/
@Slf4j
@Component
public class IpUtils {

public static byte[] IP2REGION_VINDEX;// ip2region的缓存文件

private static String ipRegionPath;

@SuppressWarnings("static-access")
@Value("${ip2region.path}")
public void setIpRegionPath(String ipRegionPath) {
this.ipRegionPath = ipRegionPath;
}

public @Data static class IpRegion {
public Boolean isSuccess;// ip转换地区是否成功
public String region;// 地区
public String country;// 国家
public String province;// 省份
public String city;// 城市
public String internet;// 网络
public String ip;// ip地址
public String message;// 错误信息
}

/**
* 初始化正确返回值
*
* @param region 解析的区域
* @param country 国家
* @param province 省份
* @param city 城市
* @param internet 网络
* @param ip ip地址
* @return
*/
public static IpRegion initIpRegionSuccess(String region, String country, String province, String city,
String internet, String ip) {
IpRegion ipm = new IpRegion();
ipm.setCity(city);
ipm.setCountry(country);
ipm.setMessage("解析成功");
ipm.setIsSuccess(true);
ipm.setIp(ip);
ipm.setRegion(region);
ipm.setProvince(province);
ipm.setInternet(internet);
return ipm;
}

/**
* 初始化错误的返回值
*
* @param ip ip地址
* @param message 错误内容
* @return
*/
public static IpRegion initIpRegionError(String ip, String message) {
IpRegion ipm = new IpRegion();
ipm.setCity("");
ipm.setCountry("");
ipm.setMessage(message);
ipm.setIsSuccess(false);
ipm.setIp(ip);
ipm.setRegion("");
ipm.setProvince("");
return ipm;
}

/**
* @desc ip转换城市
* @param ip
* @return
*/
public static IpRegion ip2region(String ip) {
log.info("ip:" + ip);
byte[] vIndex = loadVIndex();
// 2、使用全局的 vIndex 创建带 VectorIndex 缓存的查询对象。
Searcher searcher;
try {
searcher = Searcher.newWithVectorIndex(ipRegionPath, vIndex);
} catch (Exception e) {
log.error("创建Searcher失败", e);
return initIpRegionError(ip, "创建Searcher失败");
}

// 3、查询
try {
String region = searcher.search(ip);
log.info("region:" + region);
// 中国|0|山东省|济南市|电信
String[] rg = region.split("\\|");
log.info("rg:" + ArrayUtils.toString(rg));
String country = rg[0].equals("0") ? "" : rg[0];
String province = rg[2].equals("0") ? "" : rg[2];
String city = rg[3].equals("0") ? "" : rg[3];
String internet = rg[4].equals("0") ? "" : rg[4];
// 4、关闭资源
searcher.close();
return initIpRegionSuccess(region, country, province, city, internet, ip);

} catch (Exception e) {
log.info("解析结果异常", e);
return initIpRegionError(ip, "解析结果异常");
}
// 备注:每个线程需要单独创建一个独立的 Searcher 对象,但是都共享全局的制度 vIndex 缓存。
}
/**
* @desc 加载ip2region.xdb文件
* @return
*/
public static byte[] loadVIndex() {
if (IP2REGION_VINDEX != null) {
return IP2REGION_VINDEX;
} else {
byte[] vIndex;
try {
vIndex = Searcher.loadVectorIndexFromFile(ipRegionPath);
IP2REGION_VINDEX = vIndex;
} catch (Exception e) {
log.info("failed to load vector index from `%s`: %s\n", ipRegionPath, e);
return null;
}
return IP2REGION_VINDEX;
}
}

public static void main(String[] args) {
String ip = "127.0.0.1";
ip2region(ip);
}
}

3.3 Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.bluedeer.wechat.controller.noauth;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.bluedeer.common.utils.RequestUtils;
import com.bluedeer.common.utils.RequestUtils.BrowserInfo;
import com.bluedeer.wechat.utils.IpUtils;
import com.bluedeer.wechat.utils.IpUtils.IpRegion;
import com.weipan.common.common.utils.R;
import com.weipan.wechat.base.BaseController.BaseController;

import lombok.extern.slf4j.Slf4j;


/**
* @desc ip地址
* @author RenJie
*
*/
@RestController
@RequestMapping("/ip")
@Slf4j
@CrossOrigin
public class IpController extends BaseController{


@GetMapping(value = "load")
public R load(HttpServletRequest request) {
BrowserInfo browserInfo = RequestUtils.loadBrowserInfo(request);
String ip = RequestUtils.loadIp(request);
IpRegion ipRegion = IpUtils.ip2region(ip);
JSONObject data = new JSONObject();
data.put("browserInfo", browserInfo);
data.put("ipRegion", ipRegion);
return R.ok().put("data", data);
}


}

*************感谢您的阅读*************