最近在做公司需求时,甲方一会提出根据IP获取所在地,一会有提出根据手机号获取手机号所在地。真的是:需求时时变,累死程序猿。甲方才是爸爸。
之前已经实现过根据IP获取所在地的几种方式,大家可以参考我之前写的文章下:《SpringBoot通过ip获取归属地的几种方式》。
那么今天我们来看看根据手机号有哪些方式可以获取归属地呢?
废话不多说,开撸!
libphonenumber:是谷歌提供的一款用于解析、格式化和校验国际手机号码的软件库。它提供了三个包,分别对应不同的功能。
:用于校验手机号的正确性,提供了:getNumberType,isNumberMatch ,getExampleNumber 等方法。
:用于获取手机号的供应商。通过初始化PhoneNumberToCarrierMapper ,调用getNameForNumber可获取运营商信息。
:用于获取手机号的归属地。通过初始化PhoneNumberOfflineGeocoder ,调用getDescriptionForNumber方法可获取手机归属地。
下面我们来说说具体实现。
引入包:
引入libphonenumber所有包后,我们编写一个工具类,实现手机校验,获取供应商,归属地等信息。
其中,getPhoneNumber创建每个手机号的Phonenumber.PhoneNumber,供其他接口调用。同时在调用运营商等接口时先进行手机号的校验。
在上面的接口中,我们会发现创建Phonenumber.PhoneNumber时,会使用setCountryCode方法去设置所在国家的电话区号,我们有时候复制手机号会发现前面是86,而86就是代表我们国家。每个国家有每个国家电话代号,其他国家代号,小伙伴们可以参考国际电信联盟根据 E.164 标准 分配给各国或特殊行政区的代码。
已经封装了工具类,那么接下来我们就测试一下,用手机号试试能不能获取归属信息。
我们直接在Controller层中编写接口:
在浏览器中输入地址,添加号码:
通过测试,引用谷歌提供的包,可以解决我们的需求。
哈哈,可以不用加班.......
虽然引入谷歌的可以搞定需求了,但是作为程序员总要想想还有没有其他方式实现?这不又找一种方式。哈哈
其实我们的手机号是有规律可循的:
1、前3位:前三位的数字,其实代表的是运营商。不同的运营商会提供不同的号段。比如:我的手机号是135开头就是移动提供的。移动除了提供135号段外,还有其他各种号段,如134,137等;联通则提供了:130,131等号段;电信呢,提供了133,153等号段。
2、前7位:前7位则是可以确定手机号的归属地,例如:我的手机号前7位是1350154,则可以确定是广东省广州市。
既然我们知道了手机号的一些规律,那么如果有一份这样的文档,我们是不是就可以基于这份文档进行归属地的查询呢?
还真有这样的一份文档,我在网上找到一份4年前的CSV文档。如图:
既然有这份文档那我们就好实现了该功能。
只所以写读取CSV文件,是因为读取到这些信息后,想怎么查询就由我们自己说了算了。可以将数据存储到数据库查询,也可以放在redis中查询。下面我们基于redis的查询来实现归属功能。
将CSV文件读取到redis中。
我们在系统启动后,自动将CSV数据加载到redis中,当然通过@ConditionalOnProperty可以来自行决定要不要加载到内存中。不知道@ConditionalOnProperty注解使用的小伙伴去我的主页可以找到这篇文章来了解。
数据被加载到内存后,那么我们就可以编写工具类来进行获取手机归属地。
有了工具类,那我们来测试一下。
直接在Controller层中编写接口:
浏览器中访问:
至此我们也可以正常的获取到手机号的归属地。
页面抓取这种方式,跟我之前的《SpringBoot通过ip获取归属地的几种方式》中的页面抓取方式是一样的,在这就不跟大家详细介绍了。
总结
文中介绍了三种方式进行手机号查询归属地的方式。
第一种:基于谷歌提供的国际解析包,引入后不用额外引入其他的东西,只需要写工具类即可,查询速度也比较快。
第二种:基于CSV文件的,不用额外引入具体的包,但是要引入CSV文件,大小在12M多,当然也可以将文件放在磁盘里,这样不用担心部署包过大。如果是基于内存查询的话,则需要依赖redis,增加了难度。
第三种:这个就不推荐了,毕竟依赖于第三方,如果服务挂了的话就没法使用了。如果用户量大的话,很可能会被第三方......,大家都懂的。
本文地址:http://lianchengexpo.xrbh.cn/quote/13142.html 迅博思语资讯 http://lianchengexpo.xrbh.cn/ , 查看更多