原创

Java获取IP归属地

方式一(failed)

通过调用第三方api接口,测了几个api接口,均拒绝提供服务

public IpAreaDTO getIpArea_OLD(String ip) {
   IpAreaDTO ipAreaDto = null;
   String URL = "https://api.beijinxuetang.com/api/common/ip";
   JSONObject jsonObject = new JSONObject();
   jsonObject.put("ip", ip);
   JSONObject json = restTemplate.postForObject(URL, jsonObject, JSONObject.class);
   if (json.getInteger("code") == 0) {
     json = json.getJSONObject("data");
     ipAreaDto = IpAreaDTO.*builder*().ip(ip)
         .nation(json.getString("nation"))
         .province(json.getString("province"))
         .city(json.getString("city"))
         .build();
   }
   return ipAreaDto;
 }

方式二(推荐)

GeoIP2,离线方式,速度快,但准确率不及方式一

从以下链接,下载GeoLite2-City.mmdb,放到resource目录下

GitHub - P3TERX/GeoLite.mmdb: MaxMind's GeoIP2 GeoLite2 Country, City, and ASN databases

https://github.com/P3TERX/GeoLite.mmdb

配置Bean

@Slf4j
 @Configuration
 public class IPDatabaseConfig {

   @Bean
   public DatabaseReader databaseReader() {
     FileInputStream database = null;
     try {
       // 创建数据库
       File resource = new ClassPathResource("GeoLite2-City.mmdb").getFile();
       database = new FileInputStream(resource);
       return new DatabaseReader.Builder(database).build();
     } catch (IOException e) {
       *log*.warn("DatabaseReader初始化失败",e);
     }
     return null;
   }
 }

调用service

@Slf4j
 @Service
 public class IpServiceImpl implements IpService {
   @Resource
   private DatabaseReader databaseReader;

   @Override
   public IpAreaDTO getIpArea(String ip) {
     if (ip.equals("127.0.0.1") || ip.equals("localhost")) return null;
     try {
       CityResponse response = databaseReader.city(InetAddress.*getByName*(ip));
       IpAreaDTO ipAreaDTO = IpAreaDTO.*builder*()
           .ip(ip)
           .city(response.getCity().getNames().get("zh-CN"))
           .province(response.getMostSpecificSubdivision().getNames().get("zh-CN"))
           .nation(response.getCountry().getNames().get("zh-CN"))
           .build();
       return ipAreaDTO;
     } catch (Exception e) {
       *log*.warn("ip归属地解析错误{}",ip);
     }
     return null;
   }
 }

生产环境出错

无法读取jar包下的mmdb文件,需要以数据流的方式读取,如下所示

@Bean
 public DatabaseReader databaseReader() {
   try {
     // 创建数据库
     InputStream resource = new ClassPathResource("GeoLite2-City.mmdb").getInputStream();
     return new DatabaseReader.Builder(resource).build();
   } catch (IOException e) {
     *log*.warn("DatabaseReader初始化失败",e);
   }
   return null;
 }

参考

方式一参考

手把手教你用Java获取IP归属地 - 小码A梦 - 博客园

https://www.cnblogs.com/jeremylai7/p/16685150.html

点评:ip查询地址不可用

Spring之RestTemplate详解 - 简书

https://www.jianshu.com/p/58949f8334f5

RestTemplate+OkHttpClient,这个实现方式不错

SpringBoot集成OkHttp - 简书

https://www.jianshu.com/p/64d9f8ea5338

方式二参考

IP信息解析和地理定位,以及免费GeoLite2-City.mmdb的使用教程_CrownP的博客-CSDN博客

https://blog.csdn.net/CrownP/article/details/101346838

关于各种实现方式的对比,可以参考

Java通过GeoLite2-City.mmdb进行IP信息查询地理定位和经纬度_BestTomDoG的博客-CSDN博客

https://blog.csdn.net/weixin_37999518/article/details/123566663

SpringBoot集成GeoLite2/GeoIP2---解析ip地址,获取信息_Tm598035415的博客-CSDN博客

https://blog.csdn.net/Tm598035415/article/details/131570844

其它思路

JAVA根据ip地址获取归属地java根据ip获取所在城市旺崽刘奶的博客-CSDN博客

https://blog.csdn.net/weixin_49128211/article/details/129795007

这种未尝试过,可以看看

获取文件路径

java获取当前路径的几种方法java test中获取当前文件路径仓爸爸java成长之路的博客-CSDN博客

https://blog.csdn.net/hong5225/article/details/74513019

本地测试代码,读取文件路径采用此种方式

Spring 应用访问Classpath路径下的文件spring获取classpath下的文件梦想画家的博客-CSDN博客

https://blog.csdn.net/neweastsun/article/details/100591046

spring实现方式下,读取文件路径采用此种方式

正文到此结束