mirror of
https://codeup.aliyun.com/64f7d6b8ce01efaafef1e678/coal/coal.git
synced 2026-01-25 15:55:18 +08:00
使用ip2region数据库
This commit is contained in:
@@ -1,29 +1,22 @@
|
||||
package cn.lihongjie.coal.ip;
|
||||
|
||||
import com.maxmind.geoip2.DatabaseReader;
|
||||
import com.maxmind.geoip2.model.CityResponse;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.lionsoul.ip2region.xdb.Searcher;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@@ -37,84 +30,38 @@ class IpQueryService {
|
||||
private String geolite2DownloadUrl;
|
||||
|
||||
private DatabaseReader reader;
|
||||
@Value("classpath:ip/ip2region.xdb")
|
||||
Resource dbFile;
|
||||
private Searcher searcher;
|
||||
|
||||
private static boolean isPrivateAddress(InetAddress inetAddress) {
|
||||
byte[] addressBytes = inetAddress.getAddress();
|
||||
int byte1 = addressBytes[0] & 0xff;
|
||||
int byte2 = addressBytes[1] & 0xff;
|
||||
|
||||
return (byte1 == 10) ||
|
||||
(byte1 == 172 && (byte2 >= 16 && byte2 <= 31)) ||
|
||||
(byte1 == 192 && byte2 == 168);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static void main(String[] args){
|
||||
System.out.println(isPrivateAddress(InetAddress.getByName("192.168.0.1")));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
|
||||
log.info("开始初始化GeoLite2-City本地数据库");
|
||||
|
||||
Path dbPath = Path.of("./GeoLite2-City/GeoLite2-City.mmdb");
|
||||
|
||||
Path dbDir = dbPath.getParent();
|
||||
if (Files.notExists(dbDir)) {
|
||||
|
||||
Files.createDirectories(dbDir);
|
||||
// 2、使用上述的 cBuff 创建一个完全基于内存的查询对象。
|
||||
try {
|
||||
searcher = Searcher.newWithBuffer(dbFile.getContentAsByteArray());
|
||||
} catch (Exception e) {
|
||||
log.warn("failed to new searcher with buffer", e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Files.exists(dbPath)) {
|
||||
|
||||
log.info("发现默认数据库文件: {}", dbPath);
|
||||
|
||||
} else if (StringUtils.isNotEmpty(environment.getProperty("geolite2.city.path"))) {
|
||||
|
||||
dbPath = Path.of(environment.getProperty("geolite2.city.path"));
|
||||
|
||||
log.info("发现环境变量数据库文件: {}", dbPath);
|
||||
|
||||
} else {
|
||||
|
||||
log.info("没有找到数据库文件, 下载数据库文件");
|
||||
|
||||
File downloadPath = dbPath.getParent().resolve("GeoLite2-City.tar.gz").toFile();
|
||||
FileUtils.copyURLToFile(
|
||||
new URL(geolite2DownloadUrl), downloadPath, 10 * 1000, 30 * 1000);
|
||||
|
||||
TarArchiveInputStream tarIn =
|
||||
new TarArchiveInputStream(
|
||||
new GzipCompressorInputStream(
|
||||
new BufferedInputStream(new FileInputStream(downloadPath))));
|
||||
|
||||
TarArchiveEntry tarEntry = tarIn.getNextTarEntry();
|
||||
Path newDbFile = null;
|
||||
// tarIn is a TarArchiveInputStream
|
||||
while (tarEntry != null) { // create a file with the same name as the tarEntry
|
||||
File destPath = dbDir.resolve(tarEntry.getName()).toFile();
|
||||
log.info(destPath.toString());
|
||||
|
||||
if (tarEntry.isDirectory()) {
|
||||
destPath.mkdirs();
|
||||
} else {
|
||||
destPath.createNewFile();
|
||||
if (destPath.getName().endsWith("mmdb")) {
|
||||
newDbFile = destPath.toPath();
|
||||
}
|
||||
// byte [] btoRead = new byte[(int)tarEntry.getSize()];
|
||||
byte[] btoRead = new byte[1024];
|
||||
// FileInputStream fin
|
||||
// = new FileInputStream(destPath.getCanonicalPath());
|
||||
BufferedOutputStream bout =
|
||||
new BufferedOutputStream(new FileOutputStream(destPath));
|
||||
int len = 0;
|
||||
|
||||
while ((len = tarIn.read(btoRead)) != -1) {
|
||||
bout.write(btoRead, 0, len);
|
||||
}
|
||||
|
||||
bout.close();
|
||||
btoRead = null;
|
||||
}
|
||||
tarEntry = tarIn.getNextTarEntry();
|
||||
}
|
||||
tarIn.close();
|
||||
|
||||
if (newDbFile != null) {
|
||||
|
||||
Files.move(newDbFile, dbPath);
|
||||
}
|
||||
}
|
||||
|
||||
reader = new DatabaseReader.Builder(dbPath.toFile()).build();
|
||||
log.info("加载 ip2region.db 成功");
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@@ -122,14 +69,21 @@ class IpQueryService {
|
||||
|
||||
if (reader != null) {
|
||||
InetAddress ipAddress = InetAddress.getByName(ipaddr);
|
||||
boolean siteLocalAddress = ipAddress.isSiteLocalAddress();
|
||||
if (siteLocalAddress) {
|
||||
if (ipAddress.isAnyLocalAddress()) {
|
||||
return "服务器本机地址";
|
||||
}
|
||||
if (ipAddress.isLoopbackAddress()) {
|
||||
return "本地回环地址";
|
||||
}
|
||||
if (isPrivateAddress(ipAddress)) {
|
||||
return "内网地址";
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
|
||||
CityResponse city = reader.city(ipAddress);
|
||||
return city.getCountry().getName() + city.getCity().getName();
|
||||
String search = searcher.search(ipaddr);
|
||||
return search.replace("|0|", "").replace("|", "");
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
|
||||
BIN
src/main/resources/ip/ip2region.xdb
Normal file
BIN
src/main/resources/ip/ip2region.xdb
Normal file
Binary file not shown.
Reference in New Issue
Block a user