java如何根據(jù)用戶請求獲取ip地址并解析省市信息
1.選型
1.1 實現(xiàn)方式
Java可以實現(xiàn)IP地址解析和省市區(qū)信息查詢,但是需要借助一些外部數(shù)據(jù)源或數(shù)據(jù)庫來實現(xiàn)。常用的方法有以下幾種:
1.1.1 本地文件解析
可以通過下載最新的IP地址段數(shù)據(jù)文件,然后在程序中解析該文件來獲取IP地址對應(yīng)的省市區(qū)等信息。不過這種方法需要手動維護(hù)IP庫文件,并且更新和查詢速度可能較慢,不適合高并發(fā)或大規(guī)模的應(yīng)用場景。
1.1.2 數(shù)據(jù)庫查詢
可以將IP地址段數(shù)據(jù)存儲在數(shù)據(jù)庫中,然后根據(jù)用戶請求的IP地址來查詢對應(yīng)的省市區(qū)等信息。常用的數(shù)據(jù)庫有MySQL、Oracle、SQL Server等。這種方法可以提高查詢效率和精度,并支持更靈活的查詢方式,但是需要考慮數(shù)據(jù)庫的設(shè)計和優(yōu)化問題。
1.1.3 第三方API代理
使用第三方IP查詢API代理來實現(xiàn)純Java的IP地址解析和省市區(qū)信息查詢。比如通過調(diào)用百度地圖API、高德地圖API等第三方服務(wù)來獲取IP地址對應(yīng)的位置信息。這種方法可以免去自行搭建IP數(shù)據(jù)庫的麻煩,同時也能保證查詢結(jié)果的準(zhǔn)確性和實時性,但需要考慮API使用頻率和費(fèi)用等問題。
1.2 常用ip定位庫
1.2.1 Ip2region
Ip2region:Ip2region是一個基于Java的IP地址定位庫,提供了快速而準(zhǔn)確的IP查詢服務(wù)。它將全球IP地址劃分為多級區(qū)域,可以根據(jù)IP地址獲取對應(yīng)的省市區(qū)信息、運(yùn)營商等詳細(xì)信息。
1.2.2 GeoLite2
GeoLite2:一款免費(fèi)的IP地址庫,由MaxMind公司開發(fā)和維護(hù),提供高精度的IP地址定位服務(wù)??赏ㄟ^下載數(shù)據(jù)庫文件或使用API來查詢IP地址對應(yīng)的位置信息。
1.2.3 IP2Location
IP2Location:一款商業(yè)化的IP地址庫,提供全球范圍內(nèi)的IP地址定位服務(wù),支持IPv4/IPv6地址解析??赏ㄟ^訂閱服務(wù)或購買數(shù)據(jù)庫文件來使用。
1.2.4 ipapi
ipapi:一款云端IP地址查詢API,提供高效和準(zhǔn)確的IP地址定位服務(wù)。支持JSON/XML格式的返回數(shù)據(jù),可根據(jù)用戶需求選擇不同的套餐和服務(wù)計劃。
1.2.5 QQWry
QQWry:國內(nèi)最廣泛使用的IP地址庫之一,提供了IP地址到省市區(qū)縣、運(yùn)營商等信息的映射??赏ㄟ^下載最新版的dat文件或使用API來實現(xiàn)IP地址定位。
1.2.6 其他
國內(nèi)還有很多其他的定位庫,如淘寶、新浪、搜狐等ip庫,有興趣的朋友自己了解下。
1.3 選擇
綜合下面幾種情況考慮最后選擇了 Ip2region1.數(shù)據(jù)來源和準(zhǔn)確性:數(shù)據(jù)是否完整、數(shù)據(jù)覆蓋率、精度和實效性等。
2.許可協(xié)議和商業(yè)使用:是否需要授權(quán)、是否可用于商業(yè)用途、是否收費(fèi)等。
3.支持的語言和平臺
…
2.pom.xml依賴
我自己使用的springboot項目,基礎(chǔ)依賴就不列舉了
<dependencies> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.4.2</version> </dependency> <dependency> <groupId>org.lionsoul</groupId> <artifactId>ip2region</artifactId> <version>2.7.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> </dependencies>
3.代碼示例
實體類接收國家、省市等信息。
@Data public class IpLocation implements Serializable { @ApiModelProperty("ip地址") private String ip; @ApiModelProperty("國家") private String country; @ApiModelProperty("省") private String province; @ApiModelProperty("省") private String city; @ApiModelProperty("服務(wù)商") private String isp; }
工具類:
@Slf4j //@UtilityClass public class IpUtils { /** * 字符常量0 */ private static final String ZERO="0"; /** * 本級ip */ private static final String LOCALHOST="127.0.0.1"; /** * 獲取客戶端的IP地址 */ public static String getIpAddress(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 (LOCALHOST.equals(ipAddress)) { // 根據(jù)網(wǎng)卡取本機(jī)配置的IP InetAddress inet = null; try { inet = InetAddress.getLocalHost(); ipAddress = inet.getHostAddress(); } catch (UnknownHostException e) { e.printStackTrace(); } } } // 對于通過多個代理轉(zhuǎn)發(fā)的情況,取第一個非unknown的IP地址。 // 這里假設(shè)第一個IP為真實IP,后面的為代理IP。 if (ipAddress != null && ipAddress.length() > 15) { if (ipAddress.indexOf(",") > 0) { ipAddress = ipAddress.substring(0, ipAddress.indexOf(",")); } } return ipAddress; } /** * 根據(jù)iP獲取歸屬地信息 * @return */ public static IpLocation getLocation(String ip) { IpLocation location = new IpLocation(); location.setIp(ip); try (InputStream inputStream = IpUtils.class.getResourceAsStream("/ip2region.xdb");) { byte[] bytes = IoUtil.readBytes(inputStream); Searcher searcher = Searcher.newWithBuffer(bytes); String region = searcher.search(ip); if (StrUtil.isAllNotBlank(region)) { // xdb返回格式 國家|區(qū)域|省份|城市|ISP, // 只有中國的數(shù)據(jù)絕大部分精確到了城市,其他國家部分?jǐn)?shù)據(jù)只能定位到國家,后前的選項全部是0 String[] result = region.split("\\|"); location.setCountry(ZERO.equals(result[0])?StrUtil.EMPTY:result[0]); location.setProvince(ZERO.equals(result[2])?StrUtil.EMPTY:result[2]); location.setCity(ZERO.equals(result[3])?StrUtil.EMPTY:result[3]); location.setIsp(ZERO.equals(result[4])?StrUtil.EMPTY:result[4]); } searcher.close(); } catch (Exception e) { log.error("ip地址解析異常,error:{}",e); return location; } return location; } }
在官網(wǎng)地址,將data目錄下的ip2region.xdb文件復(fù)制到resource下。
在百度輸入ip地址查詢,可以查到自己本地公網(wǎng)地址,測試如下(這里為了方便,直接寫在了工具類里):
如果需要測試 IP 地址查詢功能,可以嘗試使用一些公共的 IP 地址,例如:
- 8.8.8.8:谷歌公共 DNS 地址,位于美國。
- 114.114.114.114:中國電信公共 DNS 地址,位于中國。
- 1.1.1.1:Cloudflare 公共 DNS 地址,位于澳大利亞。
- 208.67.222.222:OpenDNS 公共 DNS 地址,位于美國。
- 176.103.130.130:AdGuard 公共 DNS 地址,位于荷蘭。
總結(jié)
到此這篇關(guān)于java如何根據(jù)用戶請求獲取ip地址并解析省市信息的文章就介紹到這了,更多相關(guān)java獲取ip地址解析省市內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中TimedCache緩存對象的詳細(xì)使用教程
TimedCache是一個泛型類,它的主要作用通常是在一定時間范圍內(nèi)對特定鍵值對進(jìn)行緩存,并且能夠根據(jù)設(shè)定的時間策略來自動清理過期的緩存項,本文給大家介紹了Java中TimedCache緩存對象的詳細(xì)使用教程,需要的朋友可以參考下2024-12-12spring使用RedisTemplate的操作類訪問Redis
本篇文章主要介紹了spring使用RedisTemplate的操作類訪問Redis,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05基于JPA實體類監(jiān)聽器@EntityListeners注解的使用實例
這篇文章主要介紹了JPA實體類監(jiān)聽器@EntityListeners注解的使用實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08SpringBoot實現(xiàn)優(yōu)雅停機(jī)的多種方式
優(yōu)雅停機(jī)(Graceful Shutdown)在現(xiàn)代微服務(wù)架構(gòu)中是非常重要的,它幫助我們確保在應(yīng)用程序停止時,不會中斷正在進(jìn)行的請求或?qū)е聰?shù)據(jù)丟失,讓我們以通俗易懂的方式來講解這個概念以及如何在 Spring Boot 中實現(xiàn)它,需要的朋友可以參考下2025-01-01Java實現(xiàn)調(diào)用ElasticSearch?API的示例詳解
這篇文章主要為大家詳細(xì)介紹了Java調(diào)用ElasticSearch?API的效果資料,文中的示例代碼講解詳細(xì),具有一定的參考價值,感興趣的可以了解一下2023-03-03Java for-each循環(huán)使用難題2例(高級使用方法)
從Java5起,在Java中有了for-each循環(huán),可以用來循環(huán)遍歷collection和array。For each循環(huán)允許你在無需保持傳統(tǒng)for循環(huán)中的索引,或在使用iterator /ListIterator時無需調(diào)用while循環(huán)中的hasNext()方法就能遍歷collection2014-04-04