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>
 | 
			
		||||
        <lombok.version>1.18.26</lombok.version>
 | 
			
		||||
        <bouncycastle.version>1.72</bouncycastle.version>
 | 
			
		||||
        <!-- 离线IP地址定位库 -->
 | 
			
		||||
        <ip2region.version>2.7.0</ip2region.version>
 | 
			
		||||
 | 
			
		||||
        <!-- 临时修复 snakeyaml 漏洞 -->
 | 
			
		||||
        <snakeyaml.version>1.33</snakeyaml.version>
 | 
			
		||||
@@ -302,6 +304,13 @@
 | 
			
		||||
                <version>${mapstruct-plus.version}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
 | 
			
		||||
            <!-- 离线IP地址定位库 ip2region -->
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>org.lionsoul</groupId>
 | 
			
		||||
                <artifactId>ip2region</artifactId>
 | 
			
		||||
                <version>${ip2region.version}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>com.ruoyi</groupId>
 | 
			
		||||
                <artifactId>ruoyi-system</artifactId>
 | 
			
		||||
 
 | 
			
		||||
@@ -90,6 +90,12 @@
 | 
			
		||||
            <artifactId>mapstruct-plus-spring-boot-starter</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <!-- 离线IP地址定位库 -->
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.lionsoul</groupId>
 | 
			
		||||
            <artifactId>ip2region</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
    </dependencies>
 | 
			
		||||
 | 
			
		||||
</project>
 | 
			
		||||
 
 | 
			
		||||
@@ -2,11 +2,6 @@ package com.ruoyi.common.core.utils.ip;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.net.NetUtil;
 | 
			
		||||
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 lombok.AccessLevel;
 | 
			
		||||
import lombok.NoArgsConstructor;
 | 
			
		||||
@@ -21,40 +16,18 @@ import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
 | 
			
		||||
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 String getRealAddressByIP(String ip) {
 | 
			
		||||
        String address = UNKNOWN;
 | 
			
		||||
        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);
 | 
			
		||||
        if (NetUtil.isInnerIP(ip)) {
 | 
			
		||||
            return "内网IP";
 | 
			
		||||
        }
 | 
			
		||||
        if (RuoYiConfig.isAddressEnabled()) {
 | 
			
		||||
            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;
 | 
			
		||||
        return RegionUtils.getCityInfo(ip);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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