获取用户ip所在城市

news/2025/9/25 17:13:17/文章来源:https://www.cnblogs.com/kohler21/p/19108715

整体流程图

获取当前登录用户所在城市,是一个非常常见的需求,在很多业务场景中用到。

比如:导航的定位功能默认选择的城市,或者一些防盗系统中识别用户两次登录的城市不一样的会有报警提示。

下载geoip2数据库

geoip2是国外的一个免费的IP库,只要注册账号就能下载IP数据库了。

官网地址:https://www.maxmind.com/。

其他下载:https://kohler.lanzouo.com/i3Fkb36wobuh

将IP库保存到电脑的某个目录下

之后使用绝对路径

引入相关依赖

引入geoip相关的依赖包:

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

增加获取城市接口

增加一个根据ip获取所在城市的接口。

创建一个GeoIpController类:

@Tag( name= "geoip操作", description = "geoip操作")
@RestController
@RequestMapping("/v1/web/geoip")
@Validated
public class GeoIpController {@Autowiredprivate GeoIpHelper geoIpHelper;/*** 根据ip获取所在城市** @param ip ip地址* @return 城市*/@NoLogin@Operation(summary = "根据ip获取所在城市", description = "根据ip获取所在城市")@GetMapping("/getCity")public CityDTO getCity(@RequestParam(value = "ip") String ip) {return geoIpHelper.getCity(ip);}
}

这个类中只包含了getCity这一个接口,该接口就是通过ip获取所在国家、省份和城市。

创建GeoIpHelper类:

@Slf4j
@Component
public class GeoIpHelper {private static final String GEO_IP_FILE_NAME = "GeoLite2-City.mmdb";@Value("${shop.mgt.geoIpFilePath:}")private String geoIpFilePath;@Value("${shop.mgt.taobaoIpUrl:}")private String taobaoIpUrl;@Value("${shop.mgt.taobaoIpRequestOff:false}")private Boolean taobaoIpRequestOff;@Autowiredprivate HttpHelper httpHelper;/*** 根据ip获取所在城市** @param ip ip地址* @return 城市*/public CityDTO getCity(String ip) {CityDTO cityFromGeoIp = getCityFromGeoIp(ip);if (Objects.nonNull(cityFromGeoIp) && Objects.nonNull(cityFromGeoIp.getCity())) {return cityFromGeoIp;}if (taobaoIpRequestOff) {return null;}return getCityFromApi(ip);}private CityDTO getCityFromGeoIp(String ip) {String fileUrl = getFileUrl();File file = new File(fileUrl);if (!file.exists()) {log.warn(String.format("%s文件不存在", fileUrl));return null;}try {DatabaseReader reader = new DatabaseReader.Builder(file).build();//解析IP地址InetAddress ipAddress = InetAddress.getByName(ip);// 获取查询结果CityResponse response = reader.city(ipAddress);if (response == null) {return null;}// 国家String country = response.getCountry().getNames().get("zh-CN");// 省份String province = response.getMostSpecificSubdivision().getNames().get("zh-CN");//城市String city = response.getCity().getNames().get("zh-CN");return new CityDTO(ip, country, province, city);} catch (Exception e) {log.error("从GeoIp库中获取城市失败,原因:", e);}return null;}private CityDTO getCityFromApi(String ip) {String url = String.format(taobaoIpUrl, ip);TaoboCityEntity taoboCityEntity = httpHelper.doGet(url, TaoboCityEntity.class);if (Objects.nonNull(taoboCityEntity)) {TaoboCityEntity.TaoboAreaEntity data = taoboCityEntity.getData();if (Objects.nonNull(data)) {return new CityDTO(ip, data.getCountry(), data.getRegion(), data.getCity());}}return null;}private String getFileUrl() {return geoIpFilePath + "/" + GEO_IP_FILE_NAME;}
}

这个类主要是来用读取IP库的数据,通过ip查询国家、省份和城市。

由于ip库有可能不全,或者不是最新的数据。可能会导致根据ip获取不到我们想要的数据的情况。

因此需要做兼容处理,如果从ip库查询不到数据,则再调用一下远程接口获取数据。

调用淘宝接口

创建HttpHelper类:

@Slf4j
@Component
public class HttpHelper {@Autowiredprivate RestTemplate restTemplate;/*** 发送get请求** @param url    url地址* @param tClass 返回值实体* @param <T>    泛型* @return 返回值实体*/public <T> T doGet(String url, Class<T> tClass) {return restTemplate.getForObject(url, tClass);}
}

定义了doGet方法获取用户请求。

创建了RestTemplateConfig类:

@Configuration
public class RestTemplateConfig {@Value("${shop.mgt.rest.template.connectTimeout:3000}")private int connectTimeout;@Value("${shop.mgt.rest.template.readTimeout:50000}")private int readTimeout;@Beanpublic RestTemplate restTemplate(ClientHttpRequestFactory factory) {return new RestTemplate(factory);}@Beanpublic ClientHttpRequestFactory simpleClientHttpRequestFactory() {HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();factory.setConnectTimeout(connectTimeout);factory.setReadTimeout(readTimeout);return factory;}/*** 忽略证书配置*/public static HttpComponentsClientHttpRequestFactory generateHttpRequestFactory()throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException {TrustStrategy acceptingTrustStrategy = (x509Certificates, authType) -> true;SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();SSLConnectionSocketFactory connectionSocketFactory = new SSLConnectionSocketFactory(sslContext,new NoopHostnameVerifier());HttpClientBuilder httpClientBuilder = HttpClients.custom();httpClientBuilder.setSSLSocketFactory(connectionSocketFactory);CloseableHttpClient httpClient = httpClientBuilder.build();HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();factory.setHttpClient(httpClient);return factory;}
}

这个类是一个配置类,主要配置了RestTemplate的一些参数,以及https请求忽略证书的情况。

如果不忽略证书,有些情况下,比如:调用测试环境的请求,使用的不是有效的证书,会请求失败。

application.yml文件中增加配置:

shop:mgt:geoIpFilePath: D:\workplace\SpringBoot\kailong_shop\shop_business\src\main\resources\files\geoip2taobaoIpUrl: https://ip.taobao.com/outGetIpInfo?ip=%s&accessKey=alibaba-inc

其中accessKey使用的淘宝的测试key。

测试

代码开发好之后,接下来进行测试。

在浏览器上访问:http://localhost:8011/v1/web/geoip/getCity?ip=123.245.11.177(我的测试路径)

返回了正确的城市

说明根据ip获取所在城市的功能OK了。

需要特别注意的是目前调用淘宝的测试接口,每天有数量限制,达到一定测试就会返回失败。

也可以换成其他平台的接口,或者申请一个付费的accessKey。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/917282.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

郑州市网站建设公司石河子规划建设局网站

文章目录 &#x1f4d6; 前言1. 认识URL && 引入http协议2. http协议格式2.1 宏观格式&#xff1a;2.2 实验演示&#xff1a; 3. http的方法3.1 GET方法&#xff1a;3.2 POST方法&#xff1a;3.3 GET vs POST&#xff1a; 4. HTTP的报头和状态码5. http的cookie5.1 htt…

电商外贸网站建设新网域名自助管理平台

ANSYS Fluent和COMSOL Multiphysics以及OpenFOAM这3款CFD软件哪个好&#xff1f;cfd软件中哪款最实用&#xff1f;cfd软件有哪些&#xff1f;今天就给大家带来这几款CFD软件对比分析&#xff0c;一起来看看吧。 ANSYS Fluent ANSYS Fluent 是一种流行的计算流体动力学 (CFD) …

【Proteus仿真】AT89C51单片机串行数据转换为并行仿真 - 实践

【Proteus仿真】AT89C51单片机串行数据转换为并行仿真 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Cons…

第13章 day14-15 Webpack逆向

Webpack逆向 Webpack是一个现代的静态模块打包工具,它主要用于前端开发中的模块化打包和构建。通过Webpack,开发者可以将多个模块(包括JavaScript、CSS、图片等)进行打包,生成优化后的静态资源文件,以供在浏览器…

Viper远程配置踩坑记录

尝试etcd做配置中心,就用了Viper。没想到踩了一堆坑,记录一下。 一开始的代码是这么写的,想着先监听再读取: func initViperRemote() {err := viper.AddRemoteProvider("etcd3","http://127.0.0.1:…

深入解析:JVM(六)-- StringTable

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

开发一个彩票网站多少钱济南医院网站建设服务公司

来源&#xff1a;AI科技评论作者&#xff1a;陈彩娴、Mr Bear编辑&#xff1a;青暮近日&#xff0c;图灵奖得主、“贝叶斯网络之父”Judea Pearl在Twitter上分享了一篇新论文“What are the most important statistical ideas of the past 50 years?”&#xff08;过去50年中最…

医院网站系统源码怎么推广引流

Linux平台 一、从yum源脚本安装部署Zabbix-Agent,添加Linux Servers/PC 概述 Zabbix 主要有以下几个组件组成: Zabbix Server:Zabbix 服务端,Zabbix的核心组件,它负责接收监控数据并触发告警,还负责将监控数据持久化到数据库中。 Zabbix Agent:Zabbix客户端,部署在被监…

国产智能体脂秤PCBA方案设计

一、产品介绍:智能体脂秤是一款高精度、多功能的健康管理工具,通过测量身体脂肪百分比、肌肉质量、骨骼密度等参数,帮助用户了解自身身体健康状况,并提供个性化的健康建议。其结构设计紧凑,外观简约时尚,适用于家…

完整教程:JRE、JDK、JVM 及 JIT 之间有什么不同?

完整教程:JRE、JDK、JVM 及 JIT 之间有什么不同?pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas"…

第15章 day18 Ast系列篇

Ast系列篇 何为混淆? 混淆可以理解为是一种对js代码加密技术,主要用于隐藏代码的真实功能,以防止js代码被逆向工程师分析和修改。通过混淆,让代码变得复杂和难以理解,使得逆向工程师在调试工程中消耗大量的时间或…

微波雷达模块在智能家居中的具体应用案例有哪些?

​微波雷达模块在智能家居中的具体应用案例有哪些?首先我们要明确什么是微波雷达? 微波是指频率在300MHz至300GHz之间的电磁波,其波长范围从1米到1毫米不等。微波具有穿透性、反射性和热效应等特点,因此在通信、加…

Ubuntu 桌面快捷方式创建增加记录

使用图形界面创建桌面快捷方式打开终端进入 GoLand 的 bin 目录:cd ~/Apps/GoLand-2024.1/bin创建桌面快捷方式文件:sudo nano /usr/share/applications/goland.desktop编写内容到文件中:[Desktop Entry] Version=1…

网站 wap 插件长春火车站是哪个站

1、 Lua&#xff1a;元表是什么&#xff0c;怎么实现对象继承 2、OPP是什么 3、mvc结构 4、C#: list和array区别和使用场景 5、项目&#xff1a; &#xff08;1&#xff09;ui框架类设计&#xff0c;ui层级管理怎么做&#xff0c;对象初始化内存占用这样做高&#xff0c;资源是…

arm64中的内存屏障指令

asm volatile("dmb osh" : : : "memory")是什么? arm架构有三种内存屏障,分别是: Data Memory Barrier, Data Synchronization Barrier, and Instruction Synchronization Barrier. OSH表示DMB…

三分

篇首语啊~~三分~你比二分多一分~——A86562U正文 顾名思义,三分会比二分多一个分区,但它是用来做什么的呢?先来偷一道拿一道例题来举例 P3382 三分 - 洛谷 我们把二分的模板偷一份拿一份过来#include<bits/stdc+…

完整教程:微服务基础2-网关路由

完整教程:微服务基础2-网关路由pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco&qu…

第21章 Day25 抖音最新ab

import requests import execjs import urllib.parsecookies = {enter_pc_once: 1,UIFID_TEMP: 163eead721bc91ca6f3a3cb4766a73c0638fabced1012e02c28bcbf3169aca5c44c51fa6beff8f1f2615be624638d06da543fe1615ff22d8…

东莞seo网站优化运营携程网站建设的意义

目录 前言1. 原理分析2. 解决方法3. 彩蛋前言 一时用不了软件,安装修复的时候也出现问题 DISM一直卡在63.2%,等了好久时间,直接强制退出寻找最终的解决方案 1. 原理分析 基本的原理查看:清理 WinSxS 文件夹 官网 主要有如下原因: 系统更新服务导致问题的存在系统文件…

wordpress模板获取数据库桂林网站seo

本文来源公众号“萝卜大杂烩”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;Polars (最强Pandas平替) 本文章转自&#xff1a;数据studio 1 介绍 Polars是一个用于操作结构化数据的高性能DataFrame库&#xff0c;可以说是平替…