SpringBoot与GeoLite2的强强联手,为您解锁全球定位的超能力。真实IP追踪?地理位置归属?轻松实现,让您的服务遍布世界各地,无疆无界!

一.概述

     GeoLite2是一款强大的数据库,用于提供地理定位服务,它包含了两个主要的产品:GeoLite2 City和GeoLite2 Country,每个季度更新一次。

  1. GeoLite2 City: 覆盖全球城市层面的地理位置数据,精确到邮政编码级别。这为需要精细定位服务的应用提供了强大的支持。

  2. GeoLite2 Country: 提供全球所有国家和地区的地理位置信息,虽然精度较GeoLite2 City略低,但足以满足大多数应用的需求。

二.代码下载

     GeoLite2-City.mmdb 代码下载,公众号天梦星科技综合服务回复GeoLite即可获取下载链接;

三.上代码

    1.pom.xml

      <!--ip地理位置转换-->
        <dependency>
            <groupId>com.maxmind.geoip2</groupId>
            <artifactId>geoip2</artifactId>
            <version>2.16.1</version>
        </dependency>

     2.Config配置类和yml

import com.maxmind.geoip2.DatabaseReader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.File;
import java.io.IOException;

@Configuration
public class GeoIPConfig {
    @Value("${customInfo.geo.path}")
    private String geoPath ;

    @Bean
    public DatabaseReader databaseReader() throws IOException {
        File database = new File(geoPath);
        return new DatabaseReader.Builder(database).build();
    }
}
#YML
customInfo:
    geo:
      path: "src/main/resources/static/GeoLite2-City.mmdb"  
      #这是本地路径,打包部署前,单独拷贝一份文件放服务器,重写服务器路径,防止打包后找不到文件问题

 3.Controller 控制类

import com.maxmind.geoip2.exception.GeoIp2Exception;
import com.portalwebsiteservice.demos.web.Dto.Result;
import com.portalwebsiteservice.demos.web.Service.GeoIPService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;


import static com.portalwebsiteservice.demos.web.Util.IpUtils.getIpAddr;


@RestController
public class GeoIPController {
    
    @Resource
    private GeoIPService geoIPService;

    @GetMapping("/geo-ip")
    public Result getGeoIPInfo(HttpServletRequest request) throws IOException, GeoIp2Exception {
        String clientIp = getIpAddr(request);
        return geoIPService.getCityInfo(clientIp);
    }
    
}

4.Service业务方法

import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.exception.GeoIp2Exception;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.record.*;
import com.portalwebsiteservice.demos.web.Dto.IpGeo;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.IOException;
import java.net.InetAddress;

@Service
public class GeoIPServiceImpl implements GeoIPService {
    @Resource
    private DatabaseReader databaseReader;

    @Override
    public Result getCityInfo(String ipAddress) throws IOException, GeoIp2Exception {
        Result result = new Result();
        InetAddress inetAddress = InetAddress.getByName(ipAddress);
        CityResponse response = databaseReader.city(inetAddress);
        if (response != null) {
            IpGeo ipGeo = new IpGeo();
            ipGeo.setCountryCode(response.getCountry().getIsoCode());
            ipGeo.setCountryNameCode(response.getCountry().getName());
            ipGeo.setCountryName(response.getCountry().getNames().get("zh-CN"));
            Subdivision province = response.getMostSpecificSubdivision();
            ipGeo.setProvinceCode(province.getIsoCode());
            ipGeo.setProvinceNameCode(province.getName());
            ipGeo.setProvinceName(province.getNames().get("zh-CN"));
            City city = response.getCity();
            ipGeo.setCityNameCode(city.getName());
            ipGeo.setCityName(city.getNames().get("zh-CN"));
            Location location = response.getLocation();
            ipGeo.setLatitude(location.getLatitude());
            ipGeo.setLongitude(location.getLongitude());
            Traits traits = response.getTraits();
            ipGeo.setNetwork(traits.getNetwork().getNetworkAddress() + "/" + traits.getNetwork().getPrefixLength());
            ipGeo.setIpAddress(traits.getIpAddress());
            result.setData(ipGeo);
        } else {
           result.setCode(400);
           result.setMsg("服务端拒绝请求!");
        }
        return result;
    }
}
import com.maxmind.geoip2.exception.GeoIp2Exception;
import java.io.IOException;

public interface GeoIPService {
    Result getCityInfo(String ipAddress) throws IOException, GeoIp2Exception;
}

 5.Dto实体类

import lombok.Data;

/**
 * IpGeo 实体类,用于存储 IP 地址相关的地理位置信息。
 */
@Data
public class IpGeo {
    // 国家简称编码
    private String countryCode;
    // 国家英文名称
    private String countryNameCode;
    // 国家中文名
    private String countryName;
    // 省份简称
    private String provinceCode;
    // 省份拼音
    private String provinceNameCode;
    // 省市名称
    private String provinceName;
    // 城市拼音
    private String cityNameCode;
    // 城市名称
    private String cityName;
    // 纬度
    private Double latitude;
    // 经度
    private Double longitude;
    // 网络信息
    private String network;
    // IP 地址
    private String ipAddress;

}

6.Util工具类获取IP真实地址

/**
 * 获取IP真实地址
 * 备注:在本地运行是获取不到真实地址,需要部署到服务上才能获取得到
 */
public class IpUtils {
        public static String getIpAddr(HttpServletRequest request) {
            String ipAddress = null;
            try {
                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")) {
                        // 根据网卡取本机配置的IP
                        InetAddress inet = null;
                        try {
                            inet = InetAddress.getLocalHost();
                        } catch (UnknownHostException e) {
                            e.printStackTrace();
                        }
                        ipAddress = inet.getHostAddress();
                    }
                }
                // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
                if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
                    // = 15
                    if (ipAddress.indexOf(",") > 0) {
                        ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                    }
                }
            } catch (Exception e) {
                ipAddress="";
            }
            return ipAddress;
        }
    }

7.接口测试返回信息:

推荐开发必备程序网站!!!

天梦星服务平台 (tmxkj.top)icon-default.png?t=N7T8https://tmxkj.top/#/

相关推荐

一步到位!用Vue轻松导出Word和Excel,同时附加多图,这个超详细教程让你成为文件处理能手!

vue 导出word文件和Excel文件,附带多张图片,封装好的js,直接调用就可以使用,简单便捷

qq_53722480的博客 4842

React 发送短信验证码和验证码校验功能组件

摘要: 该代码实现了一个带键盘跟随功能的验证码输入组件,主要特性包括: 响应式设计:通过useVisualViewport钩子检测键盘高度,自动调整输入框位置避免遮挡 验证码输入:支持6位数字输入,包含复制粘贴功能和样式化输入框显示 交互功能: 自动发送验证码 60秒重发倒计时 键盘弹出时自动聚焦输入框 UI组件:包含关闭按钮、手机号显示、验证码输入框和确认按钮 动画效果:淡入/上滑动画,输入框激活状态视觉效果 组件适用于移动端验证场景,提供良好的键盘交互体验。

qq_53722480的博客 311

Vue项目使用ssh2-sftp-client实现打包自动上传到服务器(完整教程)

🚀 Vue项目自动化部署方案 本教程教你使用ssh2-sftp-client实现Vue项目打包后自动上传服务器,告别手动拖拽! 核心功能: ✅ 打包后自动上传dist目录至服务器 ✅ 支持增量上传与文件权限保留 ✅ 可视化进度条与错误诊断 实现步骤: 安装依赖:ssh2-sftp-client + progress 配置package.json脚本,合并打包与部署 编写deploy.js核心代码,实现: SSH连接与认证 递归扫描本地文件 实时上传进度显示 错误分类处理(连接、认证、文件缺失等)

qq_53722480的博客 562

在React框架中使用Braft Editor集成Table表格的详细教程

BraftEditor是一款基于React的富文本编辑器,支持表格、多媒体和自定义样式功能。安装需使用npm或yarn添加braft-editor、braft-extensions和braft-utils三个核心包。配置包含默认控件设置(如字体、对齐、表格等)和表格扩展参数(行列数、边框样式)。使用示例展示了如何初始化编辑器、插入内容并获取HTML输出。该编辑器适用于CMS系统、报表工具等需要数据展示的场景,支持从WPS等办公软件复制内容。

qq_53722480的博客 614

vue+ts+TinyEditor 是基于 Quill 2.0 开发的富文本编辑器,提供丰富的扩展功能,适用于现代 Web 开发的完整安装使用教程

TinyEditor是基于Quill 2.0开发的富文本编辑器,提供丰富的扩展功能。安装步骤包括:1)安装核心依赖包;2)配置类型声明文件;3)更新tsconfig.json。核心代码示例展示了如何集成语法高亮、数学公式、截图等功能,并通过Vue组件实现编辑器与预览同步更新。编辑器支持多种工具栏配置选项,包括文本样式、列表、插入链接/图片/表情等,并提供@提及功能。该编辑器开箱即用,适合需要强大富文本编辑功能的项目集成。

qq_53722480的博客 622

「2025最新版React+Ant Design+Router+TailwindCss全栈攻略:从零到实战,打造高颜值企业级应用

高效开发秘籍:React+Ant Design+Router最新版整合教程,快速打造高颜值应用

qq_53722480的博客 1431

React安装使用教程

React+Ant Design+路由+axios+代码+环境配置+状态管理配置完整教程

qq_53722480的博客 998

深入解析:Vue3使用ECharts图表库实现饼图高亮(动图)的方法

【代码】深入解析:Vue3使用ECharts图表库实现饼图高亮(动图)的方法。

qq_53722480的博客 558

Vue 3: 通过图片链接获取图片颜色,间接设置背景颜色

在现代Web开发中,动态获取和处理图像数据是一个常见的需求。例如,你可能希望自动提取一张图片的主色调,以便根据这些颜色进行UI主题调整或其他视觉效果的处理。本文将介绍如何在Vue 3项目中,通过一个图片链接获取图片的颜色信息。适用场景:设置背景色(例如:根据音乐图片设置主题色)案例地址:(音乐模块的歌词)天梦星科技官网。

qq_53722480的博客 861

Vue3 与 Spline 的完美融合:打造动态背景的极致体验

Vue3 与 Spline 的完美融合:打造动态背景的极致体验

qq_53722480的博客 939

Vue 3 Vite 项目打包优化:自动删除指定文件的方法

在 Vue 3 项目中,如果你需要在打包之前删除指定的文件,可以使用 Node.js 的。3.如果需要获取到 package.json 里面的相关信息,例如获取version 版本号。文件中配置一个自定义的 Webpack 插件来完成。

qq_53722480的博客 1564

告别繁琐配置!Node.js安装与环境变量设置全攻略!

node 安装教程

qq_53722480的博客 1924

Java开发者必备!0元学习Maven环境最新版超详细配置教程

程序员必备宝典本教程旨在为 Java 开发者提供一份详尽且易于理解的 Maven 仓库配置指南,帮助你从零开始搭建高效的 Maven 开发环境。无论你是初学者还是有经验的开发者,通过本教程你都能掌握 Maven 仓库配置的核心技能,从而提升项目构建效率和依赖管理的能力。程序员必备宝典。

qq_53722480的博客 586

Spring Boot 3 文件管理:上传、下载、预览、查询与删除(全网最全面教程)

如何使用Spring Boot 3进行文件的上传、下载、预览、查询与删除操作,并提供一个完整的示例代码

qq_53722480的博客 1275

HTML+CSS 动态彩色背景

【代码】HTML+CSS 动态彩色背景。

qq_53722480的博客 460

前端开发必备:实用Tool封装工具类方法大全

程序员必备宝典网站。

qq_53722480的博客 465

Vue3+Vite配置代理隐藏真实请求地址,让你的前端开发更加安全高效!

配置代理隐藏真实请求地址

qq_53722480的博客 985

将CSS OKLCH颜色转换为十六进制HEX颜色和十六进制整数格式

我查找了全网都查不到OKLCH()方法是颜色转换方法,那今天小编就给大家分享我的方法,可能会有点点误差,但是大体不影响。好了,话不多说,直接上CssUtil代码!

qq_53722480的博客 1237

Vue前端浏览器指纹获取:数字世界的身份密码

多种数据源:从多个数据源收集信息,包括但不限于用户代理、屏幕分辨率、系统字体、WebGL、Web Audio、Canvas 等。跨浏览器兼容性:支持所有主流浏览器,包括 Chrome、Firefox、Safari、Edge 等。自定义:开发者可以根据自己的需求选择性地启用或禁用某些数据收集功能,以符合特定的隐私政策或法律要求。实时生成:在用户访问网站时实时生成指纹,无需额外的服务器处理。轻量级:库的体积相对较小,不会显著增加网页的加载时间。安全:生成的指纹通常是加密的,以减少数据泄露的风险。

qq_53722480的博客 1457

springboot 整合酷狗获取MV视频最高画质(使用自己账户)

在此声明,本内容仅供个人学习、研究或娱乐之用,严禁任何形式的商业用途。若您发现本内容被用于商业目的,请立即删除,及时与小编联系,我们将删除原代码。

qq_53722480的博客 558

SpringBoot 整合酷狗获取下载音乐(需要自己账户)

为了营造一个健康、积极的网络环境,我们鼓励用户遵守相关法律法规,尊重他人劳动成果,不进行任何形式的侵权行为。同时,我们也将持续优化内容审核机制,加强对侵权行为的打击力度,保障广大用户的合法权益。在此声明,本内容仅供个人学习、研究或娱乐之用,严禁任何形式的商业用途。若您发现本内容被用于商业目的,请立即与我们联系,我们将删除原代码。如有任何疑问或建议,欢迎随时联系小编。我们将竭诚为您提供帮助,共同维护一个和谐、有序的网络空间。(4)Dto 实体类KuGouHand。(3) 上请求示例代码。

qq_53722480的博客 695

SpringBoot项目运行时出现javax.net.ssl.SSLHandshakeException: PKIX路径构建失败:sun.security异常(本地/部署后)

javax.net.ssl.SSLHandshakeException: PKIX

qq_53722480的博客 3434

SpringBoot3与AOP完美结合:轻松追踪用户操作,实现精准日志记录

“SpringBoot3与AOP完美结合”方案提供了一个简洁、高效且灵活的方式来实现用户操作的日志记录,使得后端开发更加便捷,同时提升了最终软件产品的质量和可靠性。

qq_53722480的博客 995

SpringBoot实现手机号归属地查询功能,轻松获取手机号码信息

SpringBoot实现手机号归属地查询功能,轻松获取手机号码信息

qq_53722480的博客 654

快速学会SpringBoot图形验证码生成:一步步教你打造安全验证

5.SmsServiceImpl业务类。6.SmsController控制方法。天梦星服务平台 (tmxkj.top)4.SmsService接口类。3.config配置类。7.推荐程序员必备网站。

qq_53722480的博客 425

立即升级你的前端技能!跟随这份Vue3项目搭建教程,从零基础到专业,一步步掌握最新Web开发技术,打造响应快速、界面优雅的现代网站。

“Vue 3 + Vite + Axios + Cookie + Pinia + Element Plus + TailwindCSS + DaisyUI + Router 4:详细项目创建与安装指南”

qq_53722480的博客 784

“使用Vue.js实现原生HTML右键点击弹出菜单的详细代码示例“(详细代码)

原生html vuejs 点击右键弹窗菜单(详细代码)

qq_53722480的博客 418

uniapp/vue 实现PDF预览功能(PDFJS),组件调用和关闭

前端必备资源网站:天梦星服务平台 (tmxkj.top)

qq_53722480的博客 1405

SpringBoo+vue3+vite整合讯飞星火3.5通过webscoket实现聊天功能(前端代码)附带展示效果

访问地址:天梦星服务平台 (tmxkj.top)后端文档:SpringBoo+vue3整合讯飞星火3.5通过webscoket实现聊天功能(全网首发)附带展示效果_springboot websocket vue3-CSDN博客。

qq_53722480的博客 1295

vue3+element-plus 表单校验和循环form表单校验

正常表单校验`、循环校验、

qq_53722480的博客 1053
上一篇: 立即升级你的前端技能!跟随这份Vue3项目搭建教程,从零基础到专业,一步步掌握最新Web开发技术,打造响应快速、界面优雅的现代网站。
下一篇: 快速学会SpringBoot图形验证码生成:一步步教你打造安全验证
开朗的网友(管理员)
开朗的网友(管理员) 天梦星科技官方账号 天梦星科技官方账号
博客等级 码龄6年 5010粉丝 66原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值