diff options
| author | doufenghu <[email protected]> | 2022-01-27 17:30:35 +0800 |
|---|---|---|
| committer | doufenghu <[email protected]> | 2022-01-27 17:30:35 +0800 |
| commit | 3a065e678a7f4c7a96e46d18907d15b89ba2b62f (patch) | |
| tree | 90eaa51b62dc7bfddacb3563b881688ec83ff0e8 | |
| parent | 6af76caa5201289b151745eff1d9864d7b33f56c (diff) | |
feature(ipLookupV2)V1.0.8 新增IP工具类,用于使用MMDB获取定位信息。功能如下:
1.更新MMDB定位库的命名,遵循地理层次体系,避免政治歧义。参考:
https://support.loqate.com/geographic-hierarchy-data/
2.原IPLookup过时,对历史的MMDB数据源保持兼容
3.支持四级及更多级的获取
| -rw-r--r-- | pom.xml | 2 | ||||
| -rw-r--r-- | src/main/java/com/zdjizhi/domain/LocationResponse.java | 3 | ||||
| -rw-r--r-- | src/main/java/com/zdjizhi/domain/LocationResponseV2.java | 198 | ||||
| -rw-r--r-- | src/main/java/com/zdjizhi/utils/AbstractIpLookup.java | 25 | ||||
| -rw-r--r-- | src/main/java/com/zdjizhi/utils/GalaxyDataBaseReader.java | 8 | ||||
| -rw-r--r-- | src/main/java/com/zdjizhi/utils/IPUtil.java | 36 | ||||
| -rw-r--r-- | src/main/java/com/zdjizhi/utils/IpLookup.java | 14 | ||||
| -rw-r--r-- | src/main/java/com/zdjizhi/utils/IpLookupV2.java | 691 | ||||
| -rw-r--r-- | src/test/java/com/zdjizhi/test/IpLookupTest.java | 3 | ||||
| -rw-r--r-- | src/test/java/com/zdjizhi/test/IpLookupV2Test.java | 57 |
10 files changed, 1015 insertions, 22 deletions
@@ -7,7 +7,7 @@ <artifactId>galaxy</artifactId> <packaging>jar</packaging> <name>galaxy</name> - <version>1.0.7</version> + <version>1.0.8</version> <description>galaxy tools for common</description> <url>http://www.zdjizhi.com/galaxy-tool</url> diff --git a/src/main/java/com/zdjizhi/domain/LocationResponse.java b/src/main/java/com/zdjizhi/domain/LocationResponse.java index e2b6c63..2df8dc6 100644 --- a/src/main/java/com/zdjizhi/domain/LocationResponse.java +++ b/src/main/java/com/zdjizhi/domain/LocationResponse.java @@ -11,7 +11,10 @@ import com.fasterxml.jackson.annotation.JsonProperty; * @Author dell * @Date 2018-10-8 18:56 * @Version 1.0 + * * @deprecated + * *<p> Use {@link LocationResponseV2} instead. **/ +@Deprecated public class LocationResponse { private String areaCode; diff --git a/src/main/java/com/zdjizhi/domain/LocationResponseV2.java b/src/main/java/com/zdjizhi/domain/LocationResponseV2.java new file mode 100644 index 0000000..f0b1c06 --- /dev/null +++ b/src/main/java/com/zdjizhi/domain/LocationResponseV2.java @@ -0,0 +1,198 @@ +package com.zdjizhi.domain;/** + * Created by dell on 2018-10-8. + */ + +import com.fasterxml.jackson.annotation.JsonProperty; + + +/** + * @ClassName CountryResponse + * @Description TODO + * @Author dell + * @Date 2018-10-8 18:56 + * @Version 1.0 + **/ +public class LocationResponseV2 { + + private String areaCode; + + private String asn; + + private String isp; + + private String latitude; + + private String longitude; + + private String country; + + private String super_administrative_area; + + private String administrative_area; + + private String sub_administrative_area; + + private String locality; + + private String dependent_locality; + + private String double_dependent_locality; + + private String organization; + + private String countryCode; + + private boolean isPrivateIP; + + + public LocationResponseV2() { + + this("", "", "", "", "", "", "", "", "", "", "", "", "", ""); + } + + public LocationResponseV2(@JsonProperty("AREA_CODE") String areaCode, @JsonProperty("ASN") String asn, + @JsonProperty("ISP") String isp, @JsonProperty("LATITUDE") String latitude, + @JsonProperty("LONGITUDE") String longitude, @JsonProperty("COUNTRY") String country, + @JsonProperty("SUPER_ADMINISTRATIVE_AREA") String super_administrative_area, @JsonProperty("ADMINISTRATIVE_AREA") String administrative_area, + @JsonProperty("SUB_ADMINISTRATIVE_AREA") String sub_administrative_area, @JsonProperty("LOCALITY") String locality, + @JsonProperty("DEPENDENT_LOCALITY") String dependent_locality, @JsonProperty("DOUBLE_DEPENDENT_LOCALITY") String double_dependent_locality, + @JsonProperty("ORGANIZATION") String organization, @JsonProperty("COUNTRY_CODE") String countryCode) { + this.areaCode = areaCode; + this.asn = asn; + this.isp = isp; + this.latitude = latitude; + this.longitude = longitude; + this.country = country; + this.super_administrative_area = super_administrative_area; + this.administrative_area = administrative_area; + this.sub_administrative_area = sub_administrative_area; + this.locality = locality; + this.dependent_locality = dependent_locality; + this.double_dependent_locality = double_dependent_locality; + this.organization = organization; + this.countryCode = countryCode; + + } + + public String getAreaCode() { + return areaCode; + } + + public void setAreaCode(String areaCode) { + this.areaCode = areaCode; + } + + public String getAsn() { + return asn; + } + + public void setAsn(String asn) { + this.asn = asn; + } + + public String getCountry() { + return country; + } + + + public void setCountry(String country) { + this.country = country; + } + + public String getIsp() { + return isp; + } + + public void setIsp(String isp) { + this.isp = isp; + } + + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } + + public String getOrganization() { + return organization; + } + + public void setOrganization(String organization) { + this.organization = organization; + } + + public String getCountryCode() { + return countryCode; + } + + public void setCountryCode(String countryCode) { + this.countryCode = countryCode; + } + + public boolean isPrivateIP() { + return isPrivateIP; + } + + public void setPrivateIP(boolean privateIP) { + isPrivateIP = privateIP; + } + + public String getSuper_administrative_area() { + return super_administrative_area; + } + + public void setSuper_administrative_area(String super_administrative_area) { + this.super_administrative_area = super_administrative_area; + } + + public String getAdministrative_area() { + return administrative_area; + } + + public void setAdministrative_area(String administrative_area) { + this.administrative_area = administrative_area; + } + + public String getSub_administrative_area() { + return sub_administrative_area; + } + + public void setSub_administrative_area(String sub_administrative_area) { + this.sub_administrative_area = sub_administrative_area; + } + + public String getLocality() { + return locality; + } + + public void setLocality(String locality) { + this.locality = locality; + } + + public String getDependent_locality() { + return dependent_locality; + } + + public void setDependent_locality(String dependent_locality) { + this.dependent_locality = dependent_locality; + } + + public String getDouble_dependent_locality() { + return double_dependent_locality; + } + + public void setDouble_dependent_locality(String double_dependent_locality) { + this.double_dependent_locality = double_dependent_locality; + } +} + diff --git a/src/main/java/com/zdjizhi/utils/AbstractIpLookup.java b/src/main/java/com/zdjizhi/utils/AbstractIpLookup.java index 4902289..942b42d 100644 --- a/src/main/java/com/zdjizhi/utils/AbstractIpLookup.java +++ b/src/main/java/com/zdjizhi/utils/AbstractIpLookup.java @@ -27,16 +27,32 @@ public abstract class AbstractIpLookup { /** * - * 获取详细定位信息 - * + * 获取到城市的3级定位信息 * @param ip ip地址,点分十进制格式,ipv4 - * @return String 城市代码,省代码,国家代码 + * @return String 国家代码,省代码,城市代码 */ public abstract String cityLookupDetail(String ip); /** * + * 获取到区县的4级定位信息 + * @param ip ip地址,点分十进制格式,ipv4 + * @return String 国家代码,省,城市,区/县 + */ + public abstract String administrativeAreaLookupDetail(String ip); + + /** + * + * 获取位置信息明细,支持7级 + * @param ip ip地址,点分十进制格式,ipv4 + * @return String 国家代码,省,城市,区/县,街道 + */ + public abstract String locationLookupDetail(String ip); + + + /** + * * 获取城市信息 * * @param ip ip地址 @@ -46,7 +62,7 @@ public abstract class AbstractIpLookup { /** * - * 获取所属省信息 + * 获取所属省/州信息 * * @param ip ip地址 * @return String 州/省代码 @@ -92,7 +108,6 @@ public abstract class AbstractIpLookup { public abstract String asnLookupInfo(String ip); - /** * * 获取AS号与组织信息 diff --git a/src/main/java/com/zdjizhi/utils/GalaxyDataBaseReader.java b/src/main/java/com/zdjizhi/utils/GalaxyDataBaseReader.java index 7641fc1..85c14b9 100644 --- a/src/main/java/com/zdjizhi/utils/GalaxyDataBaseReader.java +++ b/src/main/java/com/zdjizhi/utils/GalaxyDataBaseReader.java @@ -10,6 +10,8 @@ import com.maxmind.geoip2.exception.GeoIp2Exception; import com.maxmind.geoip2.model.*; import com.zdjizhi.domain.LocationResponse; import com.zdjizhi.domain.JsonInjector; +import com.zdjizhi.domain.LocationResponseV2; + import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -182,6 +184,12 @@ public class GalaxyDataBaseReader { } + public LocationResponseV2 locationV2(InetAddress ipAddress) throws IOException, GeoIp2Exception { + return this.get(ipAddress, LocationResponseV2.class, ""); + + } + + public void close() throws IOException { this.reader.close(); diff --git a/src/main/java/com/zdjizhi/utils/IPUtil.java b/src/main/java/com/zdjizhi/utils/IPUtil.java index db459d4..8f80fe5 100644 --- a/src/main/java/com/zdjizhi/utils/IPUtil.java +++ b/src/main/java/com/zdjizhi/utils/IPUtil.java @@ -147,15 +147,6 @@ public class IPUtil { } - - - - - - - - - /** * 获得两个IP间的范围,如192.168.0.128-192.168.2.256。 * 注意:本方法不做合法性检查! @@ -566,13 +557,33 @@ public class IPUtil { /** + * @deprecated + * <p> Use {@link IPUtil#isIPv4Address(String)} instead. + */ + @Deprecated + public static boolean isIP(String ip) { + return isIPv4Address(ip); + } + + /** + * + * <p>验证字符串是否为Ip格式,包含IPv4或IPv6</p> + * @param ip ip字符 + * @return <code>true</code> ip符合验证规则, <code>false</code> ip不符合验证规则. + */ + public static boolean isIPAddress(String ip) { + return isIPv4Address(ip) || isIPv6Address(ip); + + } + + /** * * <p>验证Ip是否符合规则.给定字符串,判断是否符合正则验证的ip格式.</p> * <pre>例子说明:</pre> * @param ip ip字符 * @return <code>true</code> ip符合验证规则, <code>false</code> ip不符合验证规则. */ - public static boolean isIP(String ip) { + public static boolean isIPv4Address(String ip) { if (ip == null) { return false; } @@ -580,7 +591,6 @@ public class IPUtil { return mat.matches(); } - public static boolean isIPv6StdAddress(final String input) { return IPV6_STD_PATTERN.matcher(input).matches(); } @@ -589,8 +599,8 @@ public class IPUtil { return IPV6_HEX_COMPRESSED_PATTERN.matcher(input).matches(); } - public static boolean isIPv6Address(final String input) { - return isIPv6StdAddress(input) || isIPv6HexCompressedAddress(input); + public static boolean isIPv6Address(final String ip) { + return isIPv6StdAddress(ip) || isIPv6HexCompressedAddress(ip); } /** diff --git a/src/main/java/com/zdjizhi/utils/IpLookup.java b/src/main/java/com/zdjizhi/utils/IpLookup.java index 0bcba16..e235a6b 100644 --- a/src/main/java/com/zdjizhi/utils/IpLookup.java +++ b/src/main/java/com/zdjizhi/utils/IpLookup.java @@ -15,7 +15,11 @@ import java.net.URL; * @Author 中电积至有限公司 darnell * @Date 2020-05-8 20:01 * @Version 1.0.2 + * @deprecated + * *<p> Use {@link IpLookupV2} instead. + * **/ +@Deprecated public final class IpLookup extends AbstractIpLookup{ enum ServiceEnum { @@ -404,6 +408,16 @@ public final class IpLookup extends AbstractIpLookup{ } @Override + public String administrativeAreaLookupDetail(String ip) { + throw new IllegalArgumentException("Unsupported Method administrativeAreaLookupDetail"); + } + + @Override + public String locationLookupDetail(String ip) { + throw new IllegalArgumentException("Unsupported Method locationLookupDetail"); + } + + @Override public String cityLookup(String ip) { LocationResponse response = getResponse(ip); diff --git a/src/main/java/com/zdjizhi/utils/IpLookupV2.java b/src/main/java/com/zdjizhi/utils/IpLookupV2.java new file mode 100644 index 0000000..91c42e6 --- /dev/null +++ b/src/main/java/com/zdjizhi/utils/IpLookupV2.java @@ -0,0 +1,691 @@ +package com.zdjizhi.utils; + +import com.google.common.base.Joiner; +import com.maxmind.db.CHMCache; +import com.maxmind.geoip2.exception.AddressNotFoundException; +import com.zdjizhi.domain.LocationResponse; +import com.zdjizhi.domain.LocationResponseV2; + +import java.io.File; +import java.io.IOException; +import java.net.InetAddress; +import java.net.URL; +import java.util.Objects; +import java.util.Optional; + +/** + * @ClassName IpLookupV2 + * @Description IP定位库与TSG四级IP定位库命名体系保持一致 + * @Author 中电积至有限公司 darnell + * @Date 2022-01-27 15:01 + * @Version 1.0.8 + **/ +public final class IpLookupV2 extends AbstractIpLookup{ + + enum ServiceEnum { + PRIVATE, PUBLIC + } + public final static String DEFAULT_DATABASE_PATH = "dat"; + private final static String DEFAULT_DB_IP_PUBLIC = "ip.mmdb"; + private final static String DEFAULT_DB_IP_PUBLIC_V4 = "ip_v4.mmdb"; + private final static String DEFAULT_DB_IP_PUBLIC_V6 = "ip_v6.mmdb"; + private final static String DEFAULT_DB_IP_PRIVATE = "ip_private.mmdb"; + private final static String DEFAULT_DB_IP_PRIVATE_V4 = "ip_private_v4.mmdb"; + private final static String DEFAULT_DB_IP_PRIVATE_V6 = "ip_private_v6.mmdb"; + + private AsnLookup asnLookup; + + private static GalaxyDataBaseReader ipLocationPublicReader; + private static GalaxyDataBaseReader ipLocationPublicReaderV4; + private static GalaxyDataBaseReader ipLocationPublicReaderV6; + + private static GalaxyDataBaseReader ipLocationPrivateReader; + private static GalaxyDataBaseReader ipLocationPrivateReaderV4; + private static GalaxyDataBaseReader ipLocationPrivateReaderV6; + + synchronized void init(Builder builder) { + try { + + if (builder.isDefaultDB) { + + File dbPublicFile = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator + + DEFAULT_DB_IP_PUBLIC); + + if (!dbPublicFile.exists()) { + URL url = IpLookupV2.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_IP_PUBLIC); + if (url != null) { + dbPublicFile = new File(url.getPath()); + } + } + + File dbPublicV4File = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator + + DEFAULT_DB_IP_PUBLIC_V4); + + if (!dbPublicV4File.exists()) { + URL url = IpLookupV2.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_IP_PUBLIC_V4); + if (url != null) { + dbPublicV4File = new File(url.getPath()); + } + } + + File dbPublicV6File = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator + + DEFAULT_DB_IP_PUBLIC_V6); + if (!dbPublicV6File.exists()) { + URL url = IpLookupV2.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_IP_PUBLIC_V6); + if (url != null) { + dbPublicV6File = new File(url.getPath()); + } + } + + File dbPrivateFile = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator + +DEFAULT_DB_IP_PRIVATE); + + if (!dbPrivateFile.exists()) { + URL url = IpLookupV2.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_IP_PRIVATE); + if (url != null) { + dbPrivateFile = new File(url.getPath()); + } + } + + + File dbPrivateV4File = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator + + DEFAULT_DB_IP_PRIVATE_V4); + + if (!dbPrivateV4File.exists()) { + URL url = IpLookupV2.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_IP_PRIVATE_V4); + if (url != null) { + dbPrivateV4File = new File(url.getPath()); + } + } + + File dbPrivateV6File = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator + + DEFAULT_DB_IP_PRIVATE_V6); + if (!dbPrivateV6File.exists()) { + URL url = IpLookupV2.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_IP_PRIVATE_V6); + if (url != null) { + dbPrivateV6File = new File(url.getPath()); + } + } + + if (dbPublicFile.exists()) { + ipLocationPublicReader = new GalaxyDataBaseReader.Builder(dbPublicFile).withCache(new CHMCache()).build(); + } + if (dbPublicV4File.exists()) { + ipLocationPublicReaderV4 = new GalaxyDataBaseReader.Builder(dbPublicV4File).withCache(new CHMCache()).build(); + } + + if (dbPublicV6File.exists()) { + ipLocationPublicReaderV6 = new GalaxyDataBaseReader.Builder(dbPublicV6File).withCache(new CHMCache()).build(); + } + + if (dbPrivateFile.exists()) { + ipLocationPrivateReader = new GalaxyDataBaseReader.Builder(dbPrivateFile).withCache(new CHMCache()).build(); + } + + if (dbPrivateV4File.exists()) { + ipLocationPrivateReaderV4 = new GalaxyDataBaseReader.Builder(dbPrivateV4File).withCache(new CHMCache()).build(); + } + + if (dbPrivateV6File.exists()) { + ipLocationPrivateReaderV6 = new GalaxyDataBaseReader.Builder(dbPrivateV6File).withCache(new CHMCache()).build(); + } + + + asnLookup = new AsnLookup.Builder(true).build(); + + } else { + + + if (StringUtil.isNotBlank(builder.ipDatabasePublicFile)) { + ipLocationPublicReader = new GalaxyDataBaseReader.Builder(new File(builder.ipDatabasePublicFile)) + .withCache(new CHMCache()).build(); + } + + if (StringUtil.isNotBlank(builder.ipDatabasePublicFileV4)) { + ipLocationPublicReaderV4 = new GalaxyDataBaseReader.Builder(new File(builder.ipDatabasePublicFileV4)) + .withCache(new CHMCache()).build(); + } + + if (StringUtil.isNotBlank(builder.ipDatabasePublicFileV6)) { + ipLocationPublicReaderV6 = new GalaxyDataBaseReader.Builder(new File(builder.ipDatabasePublicFileV6)) + .withCache(new CHMCache()).build(); + } + + if (StringUtil.isNotBlank(builder.ipDatabasePrivateFile)) { + ipLocationPrivateReader = new GalaxyDataBaseReader.Builder(new File(builder.ipDatabasePrivateFile)) + .withCache(new CHMCache()).build(); + } + + if (StringUtil.isNotBlank(builder.ipDatabasePrivateFileV4)) { + ipLocationPrivateReaderV4 = new GalaxyDataBaseReader.Builder(new File(builder.ipDatabasePrivateFileV4)) + .withCache(new CHMCache()).build(); + } + + if (StringUtil.isNotBlank(builder.ipDatabasePrivateFileV6)) { + ipLocationPrivateReaderV6 = new GalaxyDataBaseReader.Builder(new File(builder.ipDatabasePrivateFileV6)) + .withCache(new CHMCache()).build(); + } + + + asnLookup = new AsnLookup.Builder(false) + .loadDataFile(builder.asnDatabasePublicFile) + .loadDataFileV4(builder.asnDatabasePublicFileV4) + .loadDataFileV6(builder.asnDatabasePublicFileV6) + .loadDataFilePrivate(builder.asnDatabasePrivateFile) + .loadDataFilePrivateV4(builder.asnDatabasePrivateFileV4) + .loadDataFilePrivateV6(builder.asnDatabasePrivateFileV6) + .build(); + + + } + + } catch (Exception e) { + + logger.error("IpLookup init data error, please check your file path!"); + + } + + + } + + + private IpLookupV2(Builder builder) { + init(builder); + } + + + + /** + * 加载mmdb数据字典文件,内部生成mmdb动态库。 + * + * 1.默认记载IP库,使用方式如下: + * IpLookup ipLookup = new IpLookup.Builder(true).build(); + * 自动加载应用dat目录下的库文件,命名为:all_ip_info_v4.mmdb与all_ip_info_v6.mmdb库。 + * + * 2.手动加载IP库,使用方式如下: + * <p> + * IpLookup ipLookup = new IpLookup.Builder(false).loadDataFileV4("D:\\galaxy-tool\\dat\\ip.mmdb"). + * loadDataFileV6("D:\\galaxy-tool\\dat\\all_ip_info_v6.mmdb").build(); + * + * </p> + */ + public static final class Builder { + String ipDatabasePublicFile; + String ipDatabasePublicFileV4; + String ipDatabasePublicFileV6; + + String ipDatabasePrivateFile; + String ipDatabasePrivateFileV4; + String ipDatabasePrivateFileV6; + + String asnDatabasePublicFile; + String asnDatabasePublicFileV4; + String asnDatabasePublicFileV6; + + String asnDatabasePrivateFile; + String asnDatabasePrivateFileV4; + String asnDatabasePrivateFileV6; + + boolean isDefaultDB; + + /** + * + * @param isDefaultDB <code>false</code> 手动指定IP库路径 <code>true</code> 使用默认路径 + */ + public Builder(boolean isDefaultDB) { + this.isDefaultDB = isDefaultDB; + } + + /** + * + * @param ipDatabasePublicFile 加载IPv4与IPV6 mmdb库文件 + * @return + */ + public Builder loadDataFile(String ipDatabasePublicFile) { + this.ipDatabasePublicFile = ipDatabasePublicFile; + return this; + } + + /** + * + * @param ipDatabasePublicFileV4 加载IPv4 mmdb库文件 + * @return + */ + public Builder loadDataFileV4(String ipDatabasePublicFileV4) { + this.ipDatabasePublicFileV4 = ipDatabasePublicFileV4; + return this; + } + + /** + * + * @param ipDatabasePublicFileV6 加载IPv6 mmdb库文件 + * @return + */ + public Builder loadDataFileV6(String ipDatabasePublicFileV6) { + this.ipDatabasePublicFileV6 = ipDatabasePublicFileV6; + return this; + } + + /** + * + * @param ipDatabasePrivateFile 加载用户自定义IPv4与IPv6 mmdb库文件 + * @return + */ + public Builder loadDataFilePrivate(String ipDatabasePrivateFile) { + this.ipDatabasePrivateFile = ipDatabasePrivateFile; + return this; + } + + /** + * + * @param ipDatabasePrivateFileV4 加载用户自定义IPv4 mmdb库文件 + * @return + */ + public Builder loadDataFilePrivateV4(String ipDatabasePrivateFileV4) { + this.ipDatabasePrivateFileV4 = ipDatabasePrivateFileV4; + return this; + } + + /** + * + * @param ipDatabasePrivateFileV6 加载用户自定义IPv6 mmdb库文件 + * @return + */ + public Builder loadDataFilePrivateV6(String ipDatabasePrivateFileV6) { + this.ipDatabasePrivateFileV6 = ipDatabasePrivateFileV6; + return this; + } + + + + /** + * + * @param asnDatabasePublicFile 加载asn IPv4与IPv6库 + * @return + */ + public Builder loadAsnDataFile(String asnDatabasePublicFile) { + this.asnDatabasePublicFile = asnDatabasePublicFile; + return this; + } + + + /** + * + * @param asnDatabasePublicFileV4 加载asn IPv4 mmdb库文件 + * @return + */ + public Builder loadAsnDataFileV4(String asnDatabasePublicFileV4) { + this.asnDatabasePublicFileV4 = asnDatabasePublicFileV4; + return this; + } + + + /** + * + * @param asnDatabasePublicFileV6 加载asn IPv6 mmdb库文件 + * @return + */ + public Builder loadAsnDataFileV6(String asnDatabasePublicFileV6) { + this.asnDatabasePublicFileV6 = asnDatabasePublicFileV6; + return this; + } + + + /** + * + * @param asnDatabasePrivateFile 加载asn用户自定义 IPv4与IPv6库 + * @return + */ + public Builder loadAsnDataFilePrivate(String asnDatabasePrivateFile) { + this.asnDatabasePrivateFile = asnDatabasePrivateFile; + return this; + } + + /** + * + * @param asnDatabasePrivateFileV4 加载asn用户自定义 IPv4 mmdb库文件 + * @return + */ + public Builder loadAsnDataFilePrivateV4(String asnDatabasePrivateFileV4) { + this.asnDatabasePrivateFileV4 = asnDatabasePrivateFileV4; + return this; + } + + + /** + * + * @param asnDatabasePrivateFileV6 加载用户自定义asn IPv6 mmdb库文件 + * @return + */ + public Builder loadAsnDataFilePrivateV6(String asnDatabasePrivateFileV6) { + this.asnDatabasePrivateFileV6 = asnDatabasePrivateFileV6; + return this; + } + + /** + * 构建对象 + * @return + * @throws IOException + */ + public IpLookupV2 build() { + return new IpLookupV2(this); + } + + } + + @Override + public String countryLookup(String ip) { + + LocationResponseV2 response = getResponse(ip); + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + if (response.isPrivateIP()) { + return PRIVATE_IP; + } + + return StringUtil.setDefaultIfEmpty(response.getCountry(), UNKNOWN).toString() ; + } + + @Override + public String cityLookupDetail(String ip) { + + LocationResponseV2 response = getResponse(ip); + + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + if (response.isPrivateIP()) { + return PRIVATE_IP; + } + + return + Joiner.on(LOCATION_SEPARATOR).useForNull("").join(response.getCountry(), + response.getSuper_administrative_area(), response.getAdministrative_area()); + } + + @Override + public String administrativeAreaLookupDetail(String ip) { + LocationResponseV2 response = getResponse(ip); + + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + if (response.isPrivateIP()) { + return PRIVATE_IP; + } + + return Joiner.on(LOCATION_SEPARATOR).useForNull("").join(response.getCountry(), + response.getSuper_administrative_area(), response.getAdministrative_area(), + response.getSub_administrative_area()); + + } + + @Override + public String locationLookupDetail(String ip) { + LocationResponseV2 response = getResponse(ip); + + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + if (response.isPrivateIP()) { + return PRIVATE_IP; + } + + return Joiner.on(LOCATION_SEPARATOR).useForNull("").join(response.getCountry(), + response.getSuper_administrative_area(), response.getAdministrative_area(), + response.getSub_administrative_area(), response.getLocality(), + response.getDependent_locality(), response.getDouble_dependent_locality()); + } + + @Override + public String cityLookup(String ip) { + LocationResponseV2 response = getResponse(ip); + + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + if (response.isPrivateIP()) { + return PRIVATE_IP; + } + + return StringUtil.setDefaultIfEmpty(response.getAdministrative_area(), UNKNOWN).toString() ; + + } + + @Override + public String getCountryCode(String ip) { + LocationResponseV2 response = getResponse(ip); + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + return StringUtil.setDefaultIfEmpty(response.getCountryCode(), UNKNOWN).toString() ; + } + + @Override + public String getRegionCode(String ip) { + LocationResponseV2 response = getResponse(ip); + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + return StringUtil.setDefaultIfEmpty(response.getAreaCode(), UNKNOWN).toString() ; + } + + @Override + public String provinceLookup(String ip) { + LocationResponseV2 response = getResponse(ip); + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + if (response.isPrivateIP()) { + return PRIVATE_IP; + } + return StringUtil.setDefaultIfEmpty(response.getSuper_administrative_area(), UNKNOWN).toString() ; + } + + + + @Override + public String latLngLookup(String ip) { + LocationResponseV2 response = getResponse(ip); + if (StringUtil.isEmpty(response) || response.isPrivateIP()) { + return UNKNOWN; + } + + return Joiner.on(LATLNG_SEPARATOR).skipNulls().join(response.getLatitude(), response.getLongitude()); + + } + + + @Override + public String cityLatLngLookup(String ip) { + return Joiner.on(OBJECT_SEPARATOR).skipNulls().join(cityLookup(ip), latLngLookup(ip)); + } + + @Override + public String asnLookup(String ip) { + return asnLookup.asnLookup(ip); + + } + + + @Override + public String asnLookupInfo(String ip) { + return asnLookup.asnLookupInfo(ip); + } + + @Override + public String asnLookupDetail(String ip) { + return asnLookup.asnLookupDetail(ip); + } + + private LocationResponseV2 getResponse(String ip) { + + ip = Optional.ofNullable(ip).orElse("").trim(); + + if (!IPUtil.isIPAddress(ip)) { + throw new IllegalArgumentException("unknown ip format :" + ip ); + } + + LocationResponseV2 response = new Context(new PrivateReader()).executeStrategy(ip); + + if (StringUtil.isEmpty(response)) { + response = new Context(new PublicReader()).executeStrategy(ip); + } + + if (StringUtil.isEmpty(response)) { + response = new Context(new InnerReader()).executeStrategy(ip); + } + + return response; + } + + + + private GalaxyDataBaseReader getIpDataBaseReaderV4(String service) { + + if (service.equalsIgnoreCase(ServiceEnum.PRIVATE.name())) { + if (StringUtil.isNotEmpty(ipLocationPrivateReaderV4)) { + return ipLocationPrivateReaderV4; + } else { + return ipLocationPrivateReader; + } + } else { + if (StringUtil.isNotEmpty(ipLocationPublicReaderV4)) { + return ipLocationPublicReaderV4; + } else { + return ipLocationPublicReader; + } + } + + } + + private GalaxyDataBaseReader getIpDataBaseReaderV6(String service) { + + if (service.equalsIgnoreCase(ServiceEnum.PRIVATE.name())) { + if (StringUtil.isNotEmpty(ipLocationPrivateReaderV6)) { + return ipLocationPrivateReaderV6; + } else { + return ipLocationPrivateReader; + } + } else { + if (StringUtil.isNotEmpty(ipLocationPublicReaderV6)) { + return ipLocationPublicReaderV6; + } else { + return ipLocationPublicReader; + } + } + + } + + interface Strategy { + LocationResponseV2 getResponse(String ip); + } + + /** + * 用户自定义IP库的执行策略 + */ + class PrivateReader implements Strategy { + @Override + public LocationResponseV2 getResponse(String ip) { + GalaxyDataBaseReader dataBaseReader = null; + LocationResponseV2 response = null; + try { + InetAddress ipAddress = InetAddress.getByName(ip); + + if (IPUtil.isIP(ip)) { + dataBaseReader = getIpDataBaseReaderV4(ServiceEnum.PRIVATE.name()); + } else if (IPUtil.isIPv6Address(ip)) { + dataBaseReader = getIpDataBaseReaderV6(ServiceEnum.PRIVATE.name()); + } + + if (StringUtil.isNotEmpty(dataBaseReader)) { + response = dataBaseReader.locationV2(ipAddress); + } + + } catch(AddressNotFoundException addressNotFoundException) { + logger.debug("Address not found ,ip is :" + ip); + } catch (Exception e) { + throw new IllegalArgumentException("ip address :" + ip +", parser error " + e); + } + return response; + } + } + /** + * 第三方服务库的执行策略,例如maxmind、IPDAT + */ + class PublicReader implements Strategy { + @Override + public LocationResponseV2 getResponse(String ip) { + GalaxyDataBaseReader dataBaseReader = null; + LocationResponseV2 response = null; + try { + InetAddress ipAddress = InetAddress.getByName(ip); + + if (IPUtil.isIP(ip)) { + dataBaseReader = getIpDataBaseReaderV4(ServiceEnum.PUBLIC.name()); + + } else if (IPUtil.isIPv6Address(ip)) { + dataBaseReader = getIpDataBaseReaderV6(ServiceEnum.PUBLIC.name()); + + } + + if (StringUtil.isNotEmpty(dataBaseReader)) { + response = dataBaseReader.locationV2(ipAddress); + } + + } catch(AddressNotFoundException addressNotFoundException) { + logger.debug("Address not found ,ip is :" + ip); + } catch (Exception e) { + throw new IllegalArgumentException("ip address :" + ip +", parser error " + e); + } + return response; + + + } + } + + /** + * 私有IP执行策略 + */ + class InnerReader implements Strategy { + @Override + public LocationResponseV2 getResponse(String ip) { + LocationResponseV2 response = null; + if(IPUtil.isIP(ip) && IPUtil.internalIp(ip)) { + response = new LocationResponseV2(); + response.setPrivateIP(true); + } + return response; + } + } + + + class Context { + private Strategy strategy; + + public Context(Strategy strategy) { + this.strategy = strategy; + } + + public LocationResponseV2 executeStrategy(String ip) { + return strategy.getResponse(ip); + } + + } + + + + +} + + + + + + + + + + + diff --git a/src/test/java/com/zdjizhi/test/IpLookupTest.java b/src/test/java/com/zdjizhi/test/IpLookupTest.java index ed95ab7..dcd2c37 100644 --- a/src/test/java/com/zdjizhi/test/IpLookupTest.java +++ b/src/test/java/com/zdjizhi/test/IpLookupTest.java @@ -1,6 +1,5 @@ package com.zdjizhi.test; -import com.zdjizhi.utils.ISO3166CodeUtil; import com.zdjizhi.utils.IpLookup; import org.apache.log4j.Logger; import org.junit.Test; @@ -56,8 +55,6 @@ public class IpLookupTest { .build(); logger.info(ipLookup.cityLookup("120.221.155.123")); - logger.info(ISO3166CodeUtil.getSubdivisionCode(ipLookup.cityLookup("220.221.155.123"))); - logger.info(ISO3166CodeUtil.getCountryCode(ipLookup.countryLookup("220.221.155.123"))); logger.info(ipLookup.countryLookup("120.221.155.223")); logger.info(ipLookup.countryLookup("120.221.155.223")); logger.info(ipLookup.getCountryCode("120.221.155.223")); diff --git a/src/test/java/com/zdjizhi/test/IpLookupV2Test.java b/src/test/java/com/zdjizhi/test/IpLookupV2Test.java new file mode 100644 index 0000000..4ada5f7 --- /dev/null +++ b/src/test/java/com/zdjizhi/test/IpLookupV2Test.java @@ -0,0 +1,57 @@ +package com.zdjizhi.test; + +import com.zdjizhi.utils.IpLookupV2; +import org.apache.log4j.Logger; +import org.junit.Test; + + +public class IpLookupV2Test { + Logger logger = Logger.getLogger(IpLookupV2Test.class); + + + @Test + public void testIpLookup() { + + IpLookupV2 ipLookup = new IpLookupV2.Builder(false) + .loadDataFileV4("dat/ip_v4_built_in.mmdb") + .loadDataFilePrivateV4("dat/ip_v4_user_defined.mmdb") + .loadDataFileV6("dat/ip_v6_built_in.mmdb") + .loadDataFilePrivateV6("dat/ip_v6_user_defined.mmdb") + .loadAsnDataFile("dat/asn_v4.mmdb") + .loadAsnDataFileV6("dat/asn_v6.mmdb") + .build(); + logger.info(ipLookup.administrativeAreaLookupDetail("1.1.1.1")); + logger.info(ipLookup.locationLookupDetail("1.1.1.1")); + logger.info(ipLookup.administrativeAreaLookupDetail("220.158.208.254")); + logger.info(ipLookup.locationLookupDetail("220.158.208.254")); + + logger.info(ipLookup.provinceLookup("217.71.108.0")); + logger.info(ipLookup.cityLookup("217.71.108.0")); + logger.info(ipLookup.cityLookupDetail("217.71.108.0")); + logger.info(ipLookup.cityLookup("120.221.155.223")); + logger.info(ipLookup.countryLookup("2001:4860:4860::8888 ")); + logger.info(ipLookup.latLngLookup("217.71.108.0")); + logger.info(ipLookup.cityLookupDetail("120.221.155.223")); + logger.info(ipLookup.cityLatLngLookup("120.221.155.223")); + logger.info(ipLookup.asnLookup("120.221.155.223")); + logger.info(ipLookup.asnLookup("203.187.160.135")); + logger.info(ipLookup.asnLookup("116.128.133.102")); + logger.info(ipLookup.asnLookupInfo("116.128.133.102")); + logger.info(ipLookup.asnLookupDetail("116.128.133.102")); + logger.info(ipLookup.asnLookup("2001:4860:4860::8888")); + logger.info(ipLookup.cityLookupDetail("202.106.0.20")); + + + } + + + + + + + + + + +} + |
