Java / Kotlin 获取通过IP获取经纬度

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-28 22:14   23   0

GeoIP

[1]. Gradle

dependencies {
compile 'com.maxmind.geoip2:geoip2:2.13.1'
}

[2]. Maven

<dependency>
<groupId>com.maxmind.geoip2</groupId>
<artifactId>geoip2</artifactId>
<version>2.13.1</version>
</dependency>

[3]. 官网API

https://dev.maxmind.com/geoip/geoip2/downloadable/

https://maxmind.github.io/GeoIP2-java/

[4]. 实例

import com.maxmind.geoip2.DatabaseReader
import io.vertx.core.http.HttpServerRequest
import io.vertx.core.json.JsonObject
import org.apache.commons.lang3.StringUtils
import org.slf4j.LoggerFactory
import java.io.File
import java.net.InetAddress

/**
 * @Author
 * @create 2020/5/27 19:48
 */
object IPUtils {
    private val logger = LoggerFactory.getLogger(IPUtils::class.java)

    /**
     * 获取客户端IP地址
     *
     * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
     * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
     */
    fun getIP(request: HttpServerRequest): String? {
        var ip: String? = null
        try {
            ip = request.getHeader("X-Forwarded-For")
            if (StringUtils.isEmpty(ip) || "unknown".equals(ip, ignoreCase = true)) {
                ip = request.getHeader("Proxy-Client-IP")
            }
            if (StringUtils.isEmpty(ip) || "unknown".equals(ip, ignoreCase = true)) {
                ip = request.getHeader("X-Real-IP")
            }
            if (StringUtils.isEmpty(ip) || ip.length == 0 || "unknown".equals(ip, ignoreCase = true)) {
                ip = request.getHeader("WL-Proxy-Client-IP")
            }
            if (StringUtils.isEmpty(ip) || "unknown".equals(ip, ignoreCase = true)) {
                ip = request.getHeader("HTTP_CLIENT_IP")
            }
            if (StringUtils.isEmpty(ip) || "unknown".equals(ip, ignoreCase = true)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR")
            }
            if (StringUtils.isEmpty(ip) || "unknown".equals(ip, ignoreCase = true)) {
                ip = request.remoteAddress().host()
            }
        } catch (e: Exception) {
            logger.error("IPUtils ERROR ", e)
        }
        return ip
    }

    /**
     *
     * @description: 获得国家
     * @param reader
     * @param ip
     * @return
     * @throws Exception
     */
    @Throws(Exception::class)
    fun getCountry(reader: DatabaseReader, ip: String?): String? {
        return reader.city(InetAddress.getByName(ip)).country.names["zh-CN"]
    }

    /**
     *
     * @description: 获得省份
     * @param reader
     * @param ip
     * @return
     * @throws Exception
     */
    @Throws(Exception::class)
    fun getProvince(reader: DatabaseReader, ip: String?): String? {
        return reader.city(InetAddress.getByName(ip)).mostSpecificSubdivision.names["zh-CN"]
    }

    /**
     *
     * @description: 获得城市
     * @param reader
     * @param ip
     * @return
     * @throws Exception
     */
    @Throws(Exception::class)
    fun getCity(reader: DatabaseReader, ip: String?): String? {
        return reader.city(InetAddress.getByName(ip)).city.names["zh-CN"]
    }

    /**
     *
     * @description: 获得经度
     * @param reader
     * @param ip
     * @return
     * @throws Exception
     */
    @Throws(Exception::class)
    fun getLongitude(reader: DatabaseReader, ip: String?): Double {
        return reader.city(InetAddress.getByName(ip)).location.longitude
    }

    /**
     *
     * @description: 获得纬度
     * @param reader
     * @param ip
     * @return
     * @throws Exception
     */
    @Throws(Exception::class)
    fun getLatitude(reader: DatabaseReader, ip: String?): Double {
        return reader.city(InetAddress.getByName(ip)).location.latitude
    }

    /**
     * ip2loc获取IP信息
     */
    fun ip2loc(mmdbPath: String, request: HttpServerRequest): JsonObject {
        try {
            // 创建 GeoLite2 数据库
            val database = File(mmdbPath)
            // 读取数据库内容
            val reader = DatabaseReader.Builder(database).build()
            // 访问IP
            val ip = getIP(request)

            return JsonObject()
                    .put("country_name", getCountry(reader, ip))
                    .put("province_name", getProvince(reader, ip))
                    .put("city_name", getCity(reader, ip))
                    .put("longitude", getLongitude(reader, ip))
                    .put("latitude", getLatitude(reader, ip))
                    .put("ip", ip)
        } catch (e: Exception) {
            logger.error("Ip address get failed: {}", e.message)
        }
        return JsonObject()
    }

    @JvmStatic
    fun main(args: Array<String>) {
        try {
            // String path = req.getSession().getServletContext().getRealPath("/WEB-INF/classes/GeoLite2-City.mmdb");
            val path = "D:/GeoLite2-City.mmdb"
            // 创建 GeoLite2 数据库
            val database = File(path)
            // 读取数据库内容
            val reader = DatabaseReader.Builder(database).build()
            // 访问IP
            val ip = "192.168.2.73"
            val site = getCountry(reader, ip) + "-" + getProvince(reader, ip) + "-" + getCity(reader, ip) + "-" + getLongitude(reader, ip) + "-" + getLatitude(reader, ip)
            println(site)

        } catch (e: Exception) {
            logger.error("Ip address get failed: {}", e.message)
        }

    }
}
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP