前言
最近网站有个新需要,获取用户ip所在归属地,于是在网上搜寻了好多材料并胜利实现,其中遇到了不长坑以及胜利解决,现记录下来分享给大家。
筹备
获取ip归属地有第三方的也有Java版本的实现,大家能够依据本人理论状况来实现。
1、第三方API查问实现(第三方实现前提是要晓得具体的IP)。
2、Java实现(本文就是应用Java来实现的)。
Java实现
我应用的是ip2region来实现的,这里留神一下,ip2region老版本是应用.db库,而新版本应用的是.xdb库,具体区别这里有个文章能够看看。
1、下载.xdb数据库,并保留到/src/resources目录下
2、引入ip2region包依赖
<dependency> <groupId>org.lionsoul</groupId> <artifactId>ip2region</artifactId> <version>2.7.0</version></dependency>
3、获取ip地址
这里咱们应用X-Forwarded-For
来获取客户端的ip,如下所示:
IpUtils.java
public static String getIpAddr(ServerHttpRequest request){ String ipAddress = null; try { List<String> xForwardedForHeader = request.getHeaders().get("X-Forwarded-For"); log.info("----------- xForwardedForHeader={}", xForwardedForHeader); if (xForwardedForHeader != null && !xForwardedForHeader.isEmpty()) { ipAddress = xForwardedForHeader.get(0); if(ipAddress.indexOf(",") != -1) { ipAddress = ipAddress.split(",")[0]; } } if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { List<String> proxyClientIPHeader = request.getHeaders().get("Proxy-Client-IP"); ipAddress = (proxyClientIPHeader != null && !proxyClientIPHeader.isEmpty()) ? proxyClientIPHeader.get(0) : null; } if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { List<String> wlProxyClientIPHeader = request.getHeaders().get("WL-Proxy-Client-IP"); ipAddress = (wlProxyClientIPHeader != null && !wlProxyClientIPHeader.isEmpty()) ? wlProxyClientIPHeader.get(0) : null; } if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { List<String> httpClientIPHeader = request.getHeaders().get("HTTP_CLIENT_IP"); ipAddress = (httpClientIPHeader != null && !httpClientIPHeader.isEmpty()) ? httpClientIPHeader.get(0) : null; } if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getRemoteAddress().getAddress().getHostAddress(); } }catch (Exception e) { log.error("IPUtils ERROR ",e); } return ipAddress; }
4、解析ip归属地
有了ip,咱们应用ip2region
来解析ip归属地,如下所示:
public static byte[] toByteArray(InputStream is) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len = is.read(buffer)) != -1) { baos.write(buffer, 0, len); } return baos.toByteArray(); } // 搜寻ip地址 public String searchIpAddr(ServerHttpRequest request){ String ip = IpUtils.getIpAddr(request); log.info("---------ip={}", ip); Searcher searcher = null; try { InputStream fileStream = new ClassPathResource("ipdb/ip2region.xdb").getInputStream(); searcher = Searcher.newWithBuffer(toByteArray(fileStream)); } catch (IOException e) { return ""; } try { String region = searcher.search(ip); searcher.close(); return region; } catch (Exception e) { } return ""; }
这段代码须要留神两点:
1、肯定要应用ClassPathResource("ipdb/ip2region.xdb").getInputStream()
获取文件地位,否则获取不到文件。
2、将文件流转换成byte[],而后应用Searcher.newWithBuffer
来解析ip归属地。
实现之后,咱们通过k8s公布到生产试试看看可不可以拿到ip归属地region
,如下所示:
IP属地:中国|0|江苏省|南京市|电信
总结
1、留神本地的ip是127.0.0.1。
2、接下来我再写一篇文章对于next.js遇到的获取不到实在Ip问题。
援用
手把手教你用Java获取IP归属地