mirror of
				https://github.com/dromara/RuoYi-Vue-Plus.git
				synced 2025-11-04 08:13:44 +08:00 
			
		
		
		
	add 新增 ip2region 实现离线IP地址定位库
This commit is contained in:
		
							
								
								
									
										9
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								pom.xml
									
									
									
									
									
								
							@@ -39,6 +39,8 @@
 | 
				
			|||||||
        <mapstruct-plus.lombok.version>0.2.0</mapstruct-plus.lombok.version>
 | 
					        <mapstruct-plus.lombok.version>0.2.0</mapstruct-plus.lombok.version>
 | 
				
			||||||
        <lombok.version>1.18.26</lombok.version>
 | 
					        <lombok.version>1.18.26</lombok.version>
 | 
				
			||||||
        <bouncycastle.version>1.72</bouncycastle.version>
 | 
					        <bouncycastle.version>1.72</bouncycastle.version>
 | 
				
			||||||
 | 
					        <!-- 离线IP地址定位库 -->
 | 
				
			||||||
 | 
					        <ip2region.version>2.7.0</ip2region.version>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <!-- 临时修复 snakeyaml 漏洞 -->
 | 
					        <!-- 临时修复 snakeyaml 漏洞 -->
 | 
				
			||||||
        <snakeyaml.version>1.33</snakeyaml.version>
 | 
					        <snakeyaml.version>1.33</snakeyaml.version>
 | 
				
			||||||
@@ -302,6 +304,13 @@
 | 
				
			|||||||
                <version>${mapstruct-plus.version}</version>
 | 
					                <version>${mapstruct-plus.version}</version>
 | 
				
			||||||
            </dependency>
 | 
					            </dependency>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <!-- 离线IP地址定位库 ip2region -->
 | 
				
			||||||
 | 
					            <dependency>
 | 
				
			||||||
 | 
					                <groupId>org.lionsoul</groupId>
 | 
				
			||||||
 | 
					                <artifactId>ip2region</artifactId>
 | 
				
			||||||
 | 
					                <version>${ip2region.version}</version>
 | 
				
			||||||
 | 
					            </dependency>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <dependency>
 | 
					            <dependency>
 | 
				
			||||||
                <groupId>com.ruoyi</groupId>
 | 
					                <groupId>com.ruoyi</groupId>
 | 
				
			||||||
                <artifactId>ruoyi-system</artifactId>
 | 
					                <artifactId>ruoyi-system</artifactId>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -90,6 +90,12 @@
 | 
				
			|||||||
            <artifactId>mapstruct-plus-spring-boot-starter</artifactId>
 | 
					            <artifactId>mapstruct-plus-spring-boot-starter</artifactId>
 | 
				
			||||||
        </dependency>
 | 
					        </dependency>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!-- 离线IP地址定位库 -->
 | 
				
			||||||
 | 
					        <dependency>
 | 
				
			||||||
 | 
					            <groupId>org.lionsoul</groupId>
 | 
				
			||||||
 | 
					            <artifactId>ip2region</artifactId>
 | 
				
			||||||
 | 
					        </dependency>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    </dependencies>
 | 
					    </dependencies>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</project>
 | 
					</project>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,11 +2,6 @@ package com.ruoyi.common.core.utils.ip;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import cn.hutool.core.net.NetUtil;
 | 
					import cn.hutool.core.net.NetUtil;
 | 
				
			||||||
import cn.hutool.http.HtmlUtil;
 | 
					import cn.hutool.http.HtmlUtil;
 | 
				
			||||||
import cn.hutool.http.HttpUtil;
 | 
					 | 
				
			||||||
import cn.hutool.json.JSONObject;
 | 
					 | 
				
			||||||
import cn.hutool.json.JSONUtil;
 | 
					 | 
				
			||||||
import com.ruoyi.common.core.config.RuoYiConfig;
 | 
					 | 
				
			||||||
import com.ruoyi.common.core.constant.Constants;
 | 
					 | 
				
			||||||
import com.ruoyi.common.core.utils.StringUtils;
 | 
					import com.ruoyi.common.core.utils.StringUtils;
 | 
				
			||||||
import lombok.AccessLevel;
 | 
					import lombok.AccessLevel;
 | 
				
			||||||
import lombok.NoArgsConstructor;
 | 
					import lombok.NoArgsConstructor;
 | 
				
			||||||
@@ -21,40 +16,18 @@ import lombok.extern.slf4j.Slf4j;
 | 
				
			|||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
 | 
					@NoArgsConstructor(access = AccessLevel.PRIVATE)
 | 
				
			||||||
public class AddressUtils {
 | 
					public class AddressUtils {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // IP地址查询
 | 
					 | 
				
			||||||
    public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 未知地址
 | 
					    // 未知地址
 | 
				
			||||||
    public static final String UNKNOWN = "XX XX";
 | 
					    public static final String UNKNOWN = "XX XX";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static String getRealAddressByIP(String ip) {
 | 
					    public static String getRealAddressByIP(String ip) {
 | 
				
			||||||
        String address = UNKNOWN;
 | 
					 | 
				
			||||||
        if (StringUtils.isBlank(ip)) {
 | 
					        if (StringUtils.isBlank(ip)) {
 | 
				
			||||||
            return address;
 | 
					            return UNKNOWN;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // 内网不查询
 | 
					        // 内网不查询
 | 
				
			||||||
        ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip);
 | 
					        ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip);
 | 
				
			||||||
        if (NetUtil.isInnerIP(ip)) {
 | 
					        if (NetUtil.isInnerIP(ip)) {
 | 
				
			||||||
            return "内网IP";
 | 
					            return "内网IP";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (RuoYiConfig.isAddressEnabled()) {
 | 
					        return RegionUtils.getCityInfo(ip);
 | 
				
			||||||
            try {
 | 
					 | 
				
			||||||
                String rspStr = HttpUtil.createGet(IP_URL)
 | 
					 | 
				
			||||||
                    .body("ip=" + ip + "&json=true", Constants.GBK)
 | 
					 | 
				
			||||||
                    .execute()
 | 
					 | 
				
			||||||
                    .body();
 | 
					 | 
				
			||||||
                if (StringUtils.isEmpty(rspStr)) {
 | 
					 | 
				
			||||||
                    log.error("获取地理位置异常 {}", ip);
 | 
					 | 
				
			||||||
                    return UNKNOWN;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                JSONObject obj = JSONUtil.parseObj(rspStr);
 | 
					 | 
				
			||||||
                String region = obj.getStr("pro");
 | 
					 | 
				
			||||||
                String city = obj.getStr("city");
 | 
					 | 
				
			||||||
                return String.format("%s %s", region, city);
 | 
					 | 
				
			||||||
            } catch (Exception e) {
 | 
					 | 
				
			||||||
                log.error("获取地理位置异常 {}", ip);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return UNKNOWN;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,70 @@
 | 
				
			|||||||
 | 
					package com.ruoyi.common.core.utils.ip;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import cn.hutool.core.io.FileUtil;
 | 
				
			||||||
 | 
					import cn.hutool.core.io.resource.ClassPathResource;
 | 
				
			||||||
 | 
					import cn.hutool.core.util.ObjectUtil;
 | 
				
			||||||
 | 
					import com.ruoyi.common.core.exception.ServiceException;
 | 
				
			||||||
 | 
					import com.ruoyi.common.core.utils.file.FileUtils;
 | 
				
			||||||
 | 
					import lombok.extern.slf4j.Slf4j;
 | 
				
			||||||
 | 
					import org.lionsoul.ip2region.xdb.Searcher;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.File;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 根据ip地址定位工具类,离线方式
 | 
				
			||||||
 | 
					 * 参考地址:<a href="https://gitee.com/lionsoul/ip2region/tree/master/binding/java">集成 ip2region 实现离线IP地址定位库</a>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @author lishuyan
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@Slf4j
 | 
				
			||||||
 | 
					public class RegionUtils {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static final Searcher SEARCHER;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static {
 | 
				
			||||||
 | 
					        String fileName = "/ip2region.xdb";
 | 
				
			||||||
 | 
					        File existFile = FileUtils.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
 | 
				
			||||||
 | 
					        if (!FileUtils.exist(existFile)) {
 | 
				
			||||||
 | 
					            ClassPathResource fileStream = new ClassPathResource(fileName);
 | 
				
			||||||
 | 
					            if (ObjectUtil.isEmpty(fileStream.getStream())) {
 | 
				
			||||||
 | 
					                throw new ServiceException("RegionUtils初始化失败,原因:IP地址库数据不存在!");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            FileUtils.writeFromStream(fileStream.getStream(), existFile);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        String dbPath = existFile.getPath();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 1、从 dbPath 加载整个 xdb 到内存。
 | 
				
			||||||
 | 
					        byte[] cBuff;
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            cBuff = Searcher.loadContentFromFile(dbPath);
 | 
				
			||||||
 | 
					        } catch (Exception e) {
 | 
				
			||||||
 | 
					            throw new ServiceException("RegionUtils初始化失败,原因:从ip2region.xdb文件加载内容失败!" + e.getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 2、使用上述的 cBuff 创建一个完全基于内存的查询对象。
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            SEARCHER = Searcher.newWithBuffer(cBuff);
 | 
				
			||||||
 | 
					        } catch (Exception e) {
 | 
				
			||||||
 | 
					            throw new ServiceException("RegionUtils初始化失败,原因:" + e.getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 根据IP地址离线获取城市
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static String getCityInfo(String ip) {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            ip = ip.trim();
 | 
				
			||||||
 | 
					            // 3、执行查询
 | 
				
			||||||
 | 
					            String region = SEARCHER.search(ip);
 | 
				
			||||||
 | 
					            return region.replace("0|", "").replace("|0", "");
 | 
				
			||||||
 | 
					        } catch (Exception e) {
 | 
				
			||||||
 | 
					            log.error("IP地址离线获取城市异常 {}", ip);
 | 
				
			||||||
 | 
					            return "未知";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static void main(String[] args){
 | 
				
			||||||
 | 
					        System.out.println(RegionUtils.getCityInfo("175.169.65.25"));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								ruoyi-common/ruoyi-common-core/src/main/resources/ip2region.xdb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								ruoyi-common/ruoyi-common-core/src/main/resources/ip2region.xdb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
		Reference in New Issue
	
	Block a user