Spring Boot 快速获取客户端 IP 地址及归属地信息

图片[1]-Spring Boot 快速获取客户端 IP 地址及归属地信息-山海云端论坛

在许多网络应用中,获取用户的 IP 地址以及其归属地是一项常见的需求。例如,在社交媒体应用程序中,显示用户的所在地可以提醒用户注意言行举止,同时也有助于治理网络水军等不良现象。本文将介绍如何利用 Java 中的 Spring Boot 框架快速实现获取用户 IP 地址以及其归属地的功能。

获取 IP 地址

要获取用户的 IP 地址,可以通过 HttpServletRequest 对象来获取。下面是一个封装了获取 IP 地址的工具类 IpUtil

<code>import javax.servlet.http.HttpServletRequest; public class IpUtil { private static final String UNKNOWN = "unknown"; private static final String HEADER_FORWARDED = "x-forwarded-for"; private static final String HEADER_PROXY = "Proxy-Client-IP"; private static final String HEADER_WL_PROXY = "WL-Proxy-Client-IP"; private static final String HEADER_HTTP = "HTTP_CLIENT_IP"; private static final String HEADER_HTTP_FORWARDED = "HTTP_X_FORWARDED_FOR"; private static final String LOCAL_IP = "127.0.0.1"; private static final String LOCAL_HOST = "localhost"; /** * 获取 IP 地址 * * @param request * @return */ public String getIpAddr(HttpServletRequest request) { String ip = request.getHeader(HEADER_FORWARDED); if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeader(HEADER_PROXY); } if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeader(HEADER_WL_PROXY); } if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeader(HEADER_HTTP); } if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeader(HEADER_HTTP_FORWARDED); } if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } if (LOCAL_IP.equalsIgnoreCase(ip) || LOCAL_HOST.equalsIgnoreCase(ip) || "0:0:0:0:0:0:0:1".equalsIgnoreCase(ip)) { try { InetAddress localHost = InetAddress.getLocalHost(); ip = localHost.getHostAddress(); } catch (UnknownHostException e) { e.printStackTrace(); } } if (ip != null && ip.length() > 15) { if (ip.indexOf(",") > 15) { ip = ip.substring(0, ip.indexOf(",")); } } return ip; } }</code>

查询 IP 归属地

要查询用户的 IP 归属地,可以使用 Ip2region,一个离线 IP 数据管理框架和定位库。该库支持亿级别的数据段和十微秒级别的查询性能。

Ip2region 简介

Ip2region 支持标准化的数据格式,数据去重和压缩,并且具有极速查询响应的特点。

Github 地址:

  1. https://github.com/lionsoul2014/ip2region

Gitee 地址:

  1. https://gitee.com/lionsoul/ip2region

使用 Ip2region 查询 IP 归属地

引入依赖

pom.xml 文件中添加如下依赖:

<code><dependency> <groupId>org.lionsoul</groupId> <artifactId>ip2region</artifactId> <version>2.6.5</version> </dependency></code>

下载 ip2region.xdb

下载地址:https://gitee.com/lionsoul/ip2region/blob/master/data/ip2region.xdb

将下载后的 ip2region.xdb 文件复制到 resources/ipdb 文件夹下。

编写工具类

<code>import org.lionsoul.ip2region.DbConfig; import org.lionsoul.ip2region.DbSearcher; import java.io.InputStream; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.regex.Matcher; import java.util.regex.Pattern; public class IpUtil { private static DbSearcher searcher; /** * 判断是否为合法 IP * * @return */ public static boolean checkIp(String ipAddress) { String ip = "([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}"; Pattern pattern = Pattern.compile(ip); Matcher matcher = pattern.matcher(ipAddress); return matcher.matches(); } /** * 在服务启动时,将 ip2region 加载到内存中 */ private static void initIp2Region() { try { InputStream inputStream = new ClassPathResource("/ipdb/ip2region.xdb").getInputStream(); byte[] bytes = FileCopyUtils.copyToByteArray(inputStream); searcher = new DbSearcher(new DbConfig(), bytes); } catch (Exception exception) { exception.printStackTrace(); } } /** * 获取 ip 所属地址 * * @param ip ip * @return */ public static String getIpRegion(String ip) { boolean isIp = checkIp(ip); if (isIp) { initIp2Region(); try { // searchIpInfo 的数据格式: 国家|区域|省份|城市|ISP String searchIpInfo = searcher.search(ip); String[] splitIpInfo = searchIpInfo.split("\\|"); if (splitIpInfo.length > 0) { if ("中国".equals(splitIpInfo[0])) { // 国内属地返回省份 return splitIpInfo[2]; } else if ("0".equals(splitIpInfo[0])) { if ("内网IP".equals(splitIpInfo[4])) { // 内网 IP return splitIpInfo[4]; } else { return ""; } } else { // 国外属地返回国家 return splitIpInfo[0]; } } } catch (Exception e) { e.printStackTrace(); } return ""; } else { throw new IllegalArgumentException("非法的IP地址"); } } }</code>

测试

<code>import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest public class IpUtilTest { private static final Logger LOGGER = LoggerFactory.getLogger(IpUtilTest.class); /** * 测试 ip 所属地址 */ @Test public void testGetIpRegion() { String ip = "220.248.12.158"; // IpRegion:上海 // String ip = "47.52.236.180"; // IpRegion:香港 // String ip = "172.22.12.123"; // IpRegion:内网IP // String ip = "164.114.53.60"; // IpRegion:美国 String ipRegion = IpUtil.getIpRegion(ip); LOGGER.info("IpRegion:{}", ipRegion); } }</code>

结语

本文介绍了如何利用 Spring Boot 快速获取用户的 IP 地址以及其归属地。通过封装工具类和集成 Ip2region,可以方便地实现这一功能。希望本文对您有所帮助!

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容