【Java】根据IP地址获取省市

简介: 【Java】根据IP地址获取省市

方案一

最近要做一个埋点的功能,需求里要求记录用户登录的IP和地点,打算利用ip2region.db实现

首先下载ip2region.db

地址:下载地址

ip2region是一套准确率99.9%的ip地址定位库,0.0x毫秒级查询,数据库文件大小只有1.6M,提供了java, php, c, python,nodejs,golang查询绑定和Binary,B树,内存三种查询算法

导入依赖

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

工具类.

package com.croot.rims.utils;

import com.google.common.io.Resources;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbSearcher;
import org.lionsoul.ip2region.Util;
import org.springframework.core.io.ClassPathResource;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URL;

public class IPUtil {

    /**
     * 获取IP地址
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if ("0:0:0:0:0:0:0:1".equals(ip)) {
            ip = "127.0.0.1";
        }
        if (ip.split(",").length > 1) {
            ip = ip.split(",")[0];
        }
        return ip;
    }

    /**
     * 根据IP地址获取城市
     * @param ip
     * @return
     */
    public static String getCityInfo(String ip) throws IOException {
        URL url = IPUtil.class.getResource("/ip2region.db");
        File file;
        file = new File("/app/project/croot_rims/package/webserver/ip2region.db");
        if (!file.exists()) {
            System.out.println("Error: Invalid ip2region.db file, filePath:" + file.getPath());
            return null;
        }
        //查询算法
        int algorithm = DbSearcher.BTREE_ALGORITHM; //B-tree
        //DbSearcher.BINARY_ALGORITHM //Binary
        //DbSearcher.MEMORY_ALGORITYM //Memory
        try {
            DbConfig config = new DbConfig();
            DbSearcher searcher = new DbSearcher(config, file.getPath());
            Method method;
            switch ( algorithm )
            {
                case DbSearcher.BTREE_ALGORITHM:
                    method = searcher.getClass().getMethod("btreeSearch", String.class);
                    break;
                case DbSearcher.BINARY_ALGORITHM:
                    method = searcher.getClass().getMethod("binarySearch", String.class);
                    break;
                case DbSearcher.MEMORY_ALGORITYM:
                    method = searcher.getClass().getMethod("memorySearch", String.class);
                    break;
                default:
                    return null;
            }
            DataBlock dataBlock;
            if (!Util.isIpAddress(ip)) {
                System.out.println("Error: Invalid ip address");
                return null;
            }
            dataBlock  = (DataBlock) method.invoke(searcher, ip);
            return dataBlock.getRegion();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

具体使用

String detail = IpUtils.getCityInfo("113.105.172.33");

具体效果

中国|华南|广东省|东莞市|电信

方案二

在Java中,我们可以使用第三方库,例如"GeoIP"来获取IP地址所对应的地理位置信息。这个库是基于MaxMind的GeoLite数据库,它包含了大量的IP地址和相应的地理位置信息。

首先,你需要下载GeoLite数据库(这是一个.dat文件),然后将其放在你的项目的某个位置。接下来,你可以编写一个函数来查询这个数据库并获取IP地址的地理位置信息。

以下是一个简单的示例:

import com.maxmind.geoip2.DatabaseReader;  
import com.maxmind.geoip2.exception.GeoIp2Exception;  
import com.maxmind.geoip2.model.CityResponse;  
import com.maxmind.geoip2.record.City;  
  
import java.io.File;  
import java.io.IOException;  
import java.net.InetAddress;  
  
public class GeoIPTest {  
    public static void main(String[] args) throws IOException, GeoIp2Exception {  
        String ipAddress = "你的IP地址";  // 替换成你要查询的IP地址  
        File database = new File("你的数据库文件路径"); // 替换成你的GeoLite数据库文件路径  
        DatabaseReader dbReader = new DatabaseReader.Builder(database).build();  
        InetAddress ip = InetAddress.getByName(ipAddress);  
        CityResponse response = dbReader.city(ip);  
        City city = response.getCity();  
        System.out.println(city.getName());  // 输出城市名  
    }  
}

注意:这个例子只能获取到城市级别的信息,如果你需要更详细的信息(比如具体的经纬度),你可以查看CityResponse对象的其他方法。

最后,别忘了将这个库添加到你的项目依赖中。如果你使用的是Maven,你可以在你的pom.xml文件中添加以下依赖:

<dependency>  
    <groupId>com.maxmind.geoip2</groupId>  
    <artifactId>geoip2</artifactId>  
    <version>2.12.0</version>  <!-- 请检查最新版本 -->  
</dependency>

以上方法即可根据IP地址获取省市信息

总结

除了使用GeoIP库之外,还有其他一些方案可以用于根据IP地址获取省市信息。以下是其中几个方案:

使用第三方API服务:有一些第三方服务提供了根据IP地址获取地理位置信息的功能,例如IP2Location和GeoIP2。这些服务通常提供了简单的API,你可以在Java中使用HTTP请求调用这些API,然后获取相应的地理位置信息。

自行搭建数据库:除了使用第三方数据库之外,你还可以自行搭建数据库来存储IP地址和相应的地理位置信息。你可以使用公开的IP地址数据源,例如IP2Location和GeoIP2,将其下载下来并存储在你的数据库中。然后,你可以编写Java程序来查询这个数据库并获取IP地址的地理位置信息。

这些方案各有优缺点。使用第三方API服务可以省去自己搭建数据库和维护的麻烦,但需要支付一定的费用。自行搭建数据库可以节省费用,但需要花费时间和精力去搭建和维护。在选择方案时,你需要根据自己的需求和实际情况进行评估和选择。

目录
相关文章
|
6月前
|
Java
Java 如何根据域名查询对应的ip地址
Java 如何根据域名查询对应的ip地址
278 3
|
5月前
|
存储
JavaWeb如何获取当前访问IP
JavaWeb如何获取当前访问IP
83 0
|
15天前
|
存储 Java
Java动态转发代理IP的实现方法
Java动态转发代理IP的实现方法
28 11
|
16天前
|
安全 Java API
java借助代理ip,解决访问api频繁导致ip被禁的问题
java借助代理ip,解决访问api频繁导致ip被禁的问题
|
16天前
|
Java Python
设置代理ip——java
设置代理ip——java
|
17天前
|
网络协议 Java API
深度剖析:Java网络编程中的TCP/IP与HTTP协议实践
【4月更文挑战第17天】Java网络编程重在TCP/IP和HTTP协议的应用。TCP提供可靠数据传输,通过Socket和ServerSocket实现;HTTP用于Web服务,常借助HttpURLConnection或Apache HttpClient。两者结合,构成网络服务基础。Java有多种高级API和框架(如Netty、Spring Boot)简化开发,助力高效、高并发的网络通信。
|
3月前
|
网络协议 Java 数据安全/隐私保护
如何使用Java实现基于TCP/IP协议的即时通讯系统
TCP/IP协议是现代计算机网络通信中最常用的协议之一,而即时通讯系统则是当前互联网应用中非常普遍的一种场景。本文将介绍如何使用Java编程语言来实现基于TCP/IP协议的即时通讯系统,包括建立服务端和客户端、发送和接收消息等方面的详细步骤和示例。
|
5月前
|
网络协议 Java 程序员
java网络编程什么是TCP/IP协议栈?
java网络编程什么是TCP/IP协议栈?
33 2
|
5月前
|
网络协议 安全 Java
Java网络编程入门指南:TCP/IP协议与Socket通信
Java网络编程入门指南:TCP/IP协议与Socket通信
63 1
|
6月前
|
Java
java 如何将ip 1.2.3.4 变成1.2.3.0/24
如果你想手动实现而不使用第三方库,你可以按照如下的方式进行。以下是一个手动实现的简单示例: ```java import java.net.InetAddress; import java.net.UnknownHostException; public class IpToCidrConverter { public static void main(String[] args) { String ipAddress = "1.2.3.4"; int subnetPrefixLength = 24; try {