Java 代码获取IP地址和所属地区的方法

本文发布于 2024年12月12日,阅读 5 次,点赞 0 次,归类于 Java

博客:https://www.emanjusaka.top

公众号:emanjusaka的编程栈

by emanjusaka from https://www.emanjusaka.top/2024/12/java-get-ip-region

本文为原创文章,可能会更新知识点以及修正文中的一些错误,全文转载请保留原文地址,避免产生因未即时修正导致的误导。

在项目中我们有时需要获取请求的 IP 地址或者 IP 所属地区,比如在日志模块可能就需要记录请求的 IP 地址。

下面给出用Java代码获取的方案,可以关注收藏以备日后所需。

所需依赖

通过 ip2region 这个库查询 IP所属地区,它拥有不同语言的客户端查询实现,具体用法和特性大家可以关注它的github

         <dependency>
             <groupId>org.lionsoul</groupId>
             <artifactId>ip2region</artifactId>
         </dependency>

xdb数据文件

ip2region.xdb文件放置在项目的src/main/resources/ip2region/目录下

该文件可以从这里下载

代码实现

获取请求IP地址

     public static String getIp(HttpServletRequest request) {
         String ip = null;
 ​
         ip = request.getHeader("x-forwarded-for");
         if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getHeader("Proxy-Client-IP");
         }
         if (StrUtil.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getHeader("WL-Proxy-Client-IP");
         }
         if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getHeader("HTTP_CLIENT_IP");
         }
         if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getHeader("HTTP_X_FORWARDED_FOR");
         }
         if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getRemoteAddr();
             if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
 ​
                 InetAddress inet = null;
                 try {
                     inet = InetAddress.getLocalHost();
                 } catch (UnknownHostException e) {
                     log.error("getIpAddress exception:", e);
                     throw new RuntimeException(e);
                 }
                 ip = inet.getHostAddress();
             }
         }
         return ip;
     }

上面代码展示了从请求头中获取到 IP 的方法,如果想深入了解请求头中关于代理IP的属性可以看下我的这篇文章HTTP请求头中表示代理IP地址的属性及获取情况

获取IP所属地区

初始化查询客户端Searcher

     private static Searcher searcher;
 ​
     @PostConstruct
     private static void initIp2regionSearcher() {
         URL url = Ip2regionUtil.class.getResource("/ip2region/ip2region.xdb");
         try {
             // 1. 从 dbPath 加载整个 xdb 到内存
             byte[] cBuff;
             cBuff = Searcher.loadContentFromFile(url.getPath());
             searcher = Searcher.newWithBuffer(cBuff);
         } catch (IOException e) {
             log.error("failed to load content from `%s`: %s\n", url.getPath(), e);
             throw new RuntimeException(e);
         }
     }

查询和解析地址代码:

     public static CityInfo getCityInfo(String ip) {
         if (StrUtil.isEmpty(ip)) {
             return null;
         }
         if (ip.split("\\.").length != 4) {
             log.info("Ip2regionUtil getCityInfo fail, ip = {}", ip);
             return null;
         }
         try {
             // 查询 IP 所属地区并解析地址信息
             String searchIpInfo = searcher.search(ip);
             String[] splitIpInfo = searchIpInfo.split("\\|");
 ​
             CityInfo cityInfo = new CityInfo();
             cityInfo.setIp(ip);
             cityInfo.setSearchIpInfo(searchIpInfo);
             cityInfo.setCountry(splitIpInfo[0]);
             cityInfo.setRegion(splitIpInfo[1]);
             cityInfo.setProvince(splitIpInfo[2]);
             cityInfo.setCity(splitIpInfo[3]);
             cityInfo.setISP(splitIpInfo[4]);
             return cityInfo;
 ​
         } catch (Exception e) {
             log.error("Ip2regionUtil getCityInfo error, ip = {}: ", ip, e);
         }
         return null;
     }

完整代码

代码如下:

 package top.emanjusaka.ip2region.util;
 ​
 import cn.hutool.core.util.StrUtil;
 import jakarta.annotation.PostConstruct;
 import jakarta.servlet.http.HttpServletRequest;
 import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
 import org.lionsoul.ip2region.xdb.Searcher;
 import org.springframework.stereotype.Component;
 ​
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.URL;
 import java.net.UnknownHostException;
 ​
 /**
  * @Author emanjusaka
  * @Date 2024/11/27 13:55
  * @Version 1.0
  */
 @Slf4j
 @Component
 public class Ip2regionUtil {
     private static Searcher searcher;
 ​
     @PostConstruct
     private static void initIp2regionSearcher() {
         URL url = Ip2regionUtil.class.getResource("/ip2region/ip2region.xdb");
         try {
             // 1. 从 dbPath 加载整个 xdb 到内存
             byte[] cBuff;
             cBuff = Searcher.loadContentFromFile(url.getPath());
             searcher = Searcher.newWithBuffer(cBuff);
         } catch (IOException e) {
             log.error("failed to load content from `%s`: %s\n", url.getPath(), e);
             throw new RuntimeException(e);
         }
     }
 ​
     public static String getIp(HttpServletRequest request) {
         String ip = null;
 ​
         ip = request.getHeader("x-forwarded-for");
         if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getHeader("Proxy-Client-IP");
         }
         if (StrUtil.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getHeader("WL-Proxy-Client-IP");
         }
         if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getHeader("HTTP_CLIENT_IP");
         }
         if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getHeader("HTTP_X_FORWARDED_FOR");
         }
         if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getRemoteAddr();
             if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
 ​
                 InetAddress inet = null;
                 try {
                     inet = InetAddress.getLocalHost();
                 } catch (UnknownHostException e) {
                     log.error("getIpAddress exception:", e);
                     throw new RuntimeException(e);
                 }
                 ip = inet.getHostAddress();
             }
         }
         return ip;
     }
 ​
     public static CityInfo getCityInfo(String ip) {
         if (StrUtil.isEmpty(ip)) {
             return null;
         }
         if (ip.split("\\.").length != 4) {
             log.info("Ip2regionUtil getCityInfo fail, ip = {}", ip);
             return null;
         }
         try {
             // 查询 IP 所属地区并解析地址信息
             String searchIpInfo = searcher.search(ip);
             String[] splitIpInfo = searchIpInfo.split("\\|");
 ​
             CityInfo cityInfo = new CityInfo();
             cityInfo.setIp(ip);
             cityInfo.setSearchIpInfo(searchIpInfo);
             cityInfo.setCountry(splitIpInfo[0]);
             cityInfo.setRegion(splitIpInfo[1]);
             cityInfo.setProvince(splitIpInfo[2]);
             cityInfo.setCity(splitIpInfo[3]);
             cityInfo.setISP(splitIpInfo[4]);
             return cityInfo;
 ​
         } catch (Exception e) {
             log.error("Ip2regionUtil getCityInfo error, ip = {}: ", ip, e);
         }
         return null;
     }
 ​
     @Data
     public static class CityInfo {
         private String ip;
         private String searchIpInfo;
         private String country;
         private String region;
         private String province;
         private String city;
         private String ISP;
     }
 }
 ​

测试代码

 package top.emanjusaka.ip2region;
 ​
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.context.SpringBootTest;
 import top.emanjusaka.ip2region.util.Ip2regionUtil;
 ​
 @SpringBootTest
 class Ip2regionApplicationTests {
 ​
     @Test
     void testIp() {
         String ip = "117.61.25.78";
         Ip2regionUtil.CityInfo cityInfo = Ip2regionUtil.getCityInfo(ip);
         System.out.println("test ip2region");
         System.out.println("ip:" + cityInfo.getIp());
         System.out.println("country:" + cityInfo.getCountry());
         System.out.println("region:" + cityInfo.getRegion());
         System.out.println("province:" + cityInfo.getProvince());
         System.out.println("city:" + cityInfo.getCity());
         System.out.println("isp:" + cityInfo.getISP());
     }
 ​
 }
 ​

测试结果:

image-20241211170437445

谦学于心,谷纳万物,静思致远,共筑收获之旅!

原文地址: https://www.emanjusaka.top/2024/12/java-get-ip-region

本篇完