Java离线IP库获取城市工具类

Java解析IP库的代码实现地理位置查询通常涉及以下几个步骤:

  1. 获取IP地址:首先需要获取访问者的IP地址。这可以通过HTTP请求中的X-Forwarded-ForClient-IP等头部信息获取,或者使用Java的InetAddress类获取本地IP地址。
  2. 查询IP库:一旦获得了IP地址,就可以使用Java代码查询IP库(通常是一个数据库或API服务)来获取地理位置信息。这可以通过执行SQL查询或发送HTTP请求来实现,具体取决于IP库的类型。
  3. 解析地理位置信息:根据IP库返回的结果,Java代码需要解析地理位置信息,例如国家、省份、城市等。这可以通过将返回的结果与已知的IP地址库进行匹配或使用第三方库来实现。
  4. 返回结果:最后,Java代码将地理位置信息返回给调用者,通常是一个Web应用程序或API服务。

 可以通过以下代码获取各个城市的所属IP以及城市名称,另外还需要自行下载离线IP库。

public class IpInfoUtil {
    public static String getIpAddr(HttpServletRequest request) {
        String ipAddress = request.getHeader("x-forwarded-for");
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
                //根据网卡取本机配置的IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                assert inet != null;
                ipAddress = inet.getHostAddress();
            }
        }
        //对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
        if (ipAddress != null && ipAddress.length() > 15) { //"***.***.***.***".length() = 15
            if (ipAddress.indexOf(",") > 0) {
                ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
            }
        }
        return ipAddress;
    }

    /**
     * 根据IP地址获取城市(基于文件方式)
     *
     * @param ip
     * @return
     */
    public static String getCityInfo(String ip) throws IOException {
        String dbPath = "ip2region.xdb";
        Searcher searcher;
        try {
//            // 这里能读到这个流,但是是找不到这个文件的
//            ClassPathResource classPathResource = new ClassPathResource("ip2region.xdb");
//            // 我们新建一个文件,把流存放到这个文件,再从这个文件里面读取数据,就可以了
//            File file = new File("ip2region.xdb");
//            FileUtils.copyInputStreamToFile(classPathResource.getInputStream(), file);
//            dbPath=file.getPath();
            searcher = Searcher.newWithFileOnly(dbPath);
        } catch (IOException e) {
            e.printStackTrace();
            return String.format("failed to create searcher with `%s`: %s
", dbPath, e);
        }
        try {
//            long sTime = System.nanoTime();
//            long cost = TimeUnit.NANOSECONDS.toMicros((System.nanoTime() - sTime));
//            System.out.printf("{region: %s, ioCount: %d, took: %d μs}
", region, searcher.getIOCount(), cost);
            return searcher.search(ip);
        } catch (Exception e) {

            System.out.printf("failed to search(%s): %s
", ip, e);
        } finally {
            // 3、关闭资源
            searcher.close();
        }
        return null;
    }
}