springboot 整合 ip2region
Ip2region是什么?
ip2region - 准确率99.9%的离线IP地址定位库,0.0x毫秒级查询,ip2region.db数据库只有数MB,提供了java,php,c,python,nodejs,golang,c#等查询绑定和Binary,B树,内存三种查询算法。
ip2region 是Git开源项目:https://github.com/lionsoul2014/ip2region
第一步
将data目录下的ip2region.xdb 文件放到resources 目录下
第二步
引入maven依赖
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>2.6.4</version>
</dependency>
第三步
配置类
@Slf4j
@Configuration
public class Ip2RegionAutoConfiguration {
@Bean
public Ip2regionSearcher ip2regionSearcher() {
InputStream ris = ClassPathResource.class.getClassLoader().getResourceAsStream("ipdb/ip2region.xdb");
// 空引用
Searcher searcher = null;
try {
// 创建
searcher = Searcher.newWithBuffer(IoUtil.readBytes(ris));
//注意:不能使用文件类型,打成jar包后,会找不到文件
//searcher = Searcher.newWithFileOnly(Objects.requireNonNull(this.getClass().getResource("/ipdb/ip2region.xdb")).getPath());
return new Ip2regionSearcher(searcher);
} catch (IOException e) {
log.error("解析ip地址失败,无法创建搜索器: {}", e);
throw new RuntimeException(e);
}
}
}
服务类
public class Ip2regionSearcher implements DisposableBean {
private static final Pattern SPLIT_PATTERN = Pattern.compile("\\|");
private final Searcher searcher;
public Ip2regionSearcher(Searcher searcher) {
this.searcher = searcher;
}
@SneakyThrows
public String searchStr(String ip) {
return searcher.search(ip);
}
public IpInfo search(String ip) {
String region = searchStr(ip);
if (region == null) {
return null;
}
IpInfo ipInfo = new IpInfo();
String[] splitInfos = SPLIT_PATTERN.split(region);
// 补齐5位
if (splitInfos.length < 5) {
splitInfos = Arrays.copyOf(splitInfos, 5);
}
ipInfo.setCountry(filterZero(splitInfos[0]));
ipInfo.setRegion(filterZero(splitInfos[1]));
ipInfo.setProvince(filterZero(splitInfos[2]));
ipInfo.setCity(filterZero(splitInfos[3]));
ipInfo.setIsp(filterZero(splitInfos[4]));
return ipInfo;
}
/**
* 数据过滤,因为 ip2Region 采用 0 填充的没有数据的字段
* @param info info
* @return info
*/
@Nullable
private String filterZero(@Nullable String info) {
// null 或 0 返回 null
if (info == null || BigDecimal.ZERO.toString().equals(info)) {
return null;
}
return info;
}
@Override
public void destroy() throws Exception {
if (this.searcher != null) {
this.searcher.close();
}
}
}
实体类
@Data
public class IpInfo {
/**
* 国家
*/
private String country;
/**
* 区域
*/
private String region;
/**
* 省
*/
private String province;
/**
* 城市
*/
private String city;
/**
* 运营商
*/
private String isp;
}
使用
@Autowired
private Ip2regionSearcher ip2regionSearcher;
IpInfo ipInfo= ip2regionSearcher.search("ip地址");
遇见的问题
由于服务是用Nginx代理的,造成在request中获取的ip地址,都是127.0.0.1,解决方式
在Nginx配置里,修改location ,加上
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
重启nginx -s reload