Java 代码获取IP地址和所属地区的方法
本文发布于 2024年12月12日,阅读 5 次,点赞
0 次,归类于
Java
公众号:emanjusaka的编程栈
by emanjusaka from https://www.emanjusaka.top/2024/12/java-get-ip-region
本文为原创文章,可能会更新知识点以及修正文中的一些错误,全文转载请保留原文地址,避免产生因未即时修正导致的误导。
在项目中我们有时需要获取请求的 IP 地址或者 IP 所属地区,比如在日志模块可能就需要记录请求的 IP 地址。
下面给出用Java代码获取的方案,可以关注收藏以备日后所需。
所需依赖
通过 ip2region
这个库查询 IP所属地区,它拥有不同语言的客户端查询实现,具体用法和特性大家可以关注它的github
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
</dependency>
xdb数据文件
ip2region.xdb
文件放置在项目的src/main/resources/ip2region/
目录下
该文件可以从这里下载
代码实现
获取请求IP地址
public static String getIp(HttpServletRequest request) {
String ip = null;
ip = request.getHeader("x-forwarded-for");
if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (StrUtil.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
log.error("getIpAddress exception:", e);
throw new RuntimeException(e);
}
ip = inet.getHostAddress();
}
}
return ip;
}
上面代码展示了从请求头中获取到 IP 的方法,如果想深入了解请求头中关于代理IP的属性可以看下我的这篇文章HTTP请求头中表示代理IP地址的属性及获取情况
获取IP所属地区
初始化查询客户端Searcher
private static Searcher searcher;
@PostConstruct
private static void initIp2regionSearcher() {
URL url = Ip2regionUtil.class.getResource("/ip2region/ip2region.xdb");
try {
// 1. 从 dbPath 加载整个 xdb 到内存
byte[] cBuff;
cBuff = Searcher.loadContentFromFile(url.getPath());
searcher = Searcher.newWithBuffer(cBuff);
} catch (IOException e) {
log.error("failed to load content from `%s`: %s\n", url.getPath(), e);
throw new RuntimeException(e);
}
}
查询和解析地址代码:
public static CityInfo getCityInfo(String ip) {
if (StrUtil.isEmpty(ip)) {
return null;
}
if (ip.split("\\.").length != 4) {
log.info("Ip2regionUtil getCityInfo fail, ip = {}", ip);
return null;
}
try {
// 查询 IP 所属地区并解析地址信息
String searchIpInfo = searcher.search(ip);
String[] splitIpInfo = searchIpInfo.split("\\|");
CityInfo cityInfo = new CityInfo();
cityInfo.setIp(ip);
cityInfo.setSearchIpInfo(searchIpInfo);
cityInfo.setCountry(splitIpInfo[0]);
cityInfo.setRegion(splitIpInfo[1]);
cityInfo.setProvince(splitIpInfo[2]);
cityInfo.setCity(splitIpInfo[3]);
cityInfo.setISP(splitIpInfo[4]);
return cityInfo;
} catch (Exception e) {
log.error("Ip2regionUtil getCityInfo error, ip = {}: ", ip, e);
}
return null;
}
完整代码
代码如下:
package top.emanjusaka.ip2region.util;
import cn.hutool.core.util.StrUtil;
import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.HttpServletRequest;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.xdb.Searcher;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
/**
* @Author emanjusaka
* @Date 2024/11/27 13:55
* @Version 1.0
*/
@Slf4j
@Component
public class Ip2regionUtil {
private static Searcher searcher;
@PostConstruct
private static void initIp2regionSearcher() {
URL url = Ip2regionUtil.class.getResource("/ip2region/ip2region.xdb");
try {
// 1. 从 dbPath 加载整个 xdb 到内存
byte[] cBuff;
cBuff = Searcher.loadContentFromFile(url.getPath());
searcher = Searcher.newWithBuffer(cBuff);
} catch (IOException e) {
log.error("failed to load content from `%s`: %s\n", url.getPath(), e);
throw new RuntimeException(e);
}
}
public static String getIp(HttpServletRequest request) {
String ip = null;
ip = request.getHeader("x-forwarded-for");
if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (StrUtil.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
log.error("getIpAddress exception:", e);
throw new RuntimeException(e);
}
ip = inet.getHostAddress();
}
}
return ip;
}
public static CityInfo getCityInfo(String ip) {
if (StrUtil.isEmpty(ip)) {
return null;
}
if (ip.split("\\.").length != 4) {
log.info("Ip2regionUtil getCityInfo fail, ip = {}", ip);
return null;
}
try {
// 查询 IP 所属地区并解析地址信息
String searchIpInfo = searcher.search(ip);
String[] splitIpInfo = searchIpInfo.split("\\|");
CityInfo cityInfo = new CityInfo();
cityInfo.setIp(ip);
cityInfo.setSearchIpInfo(searchIpInfo);
cityInfo.setCountry(splitIpInfo[0]);
cityInfo.setRegion(splitIpInfo[1]);
cityInfo.setProvince(splitIpInfo[2]);
cityInfo.setCity(splitIpInfo[3]);
cityInfo.setISP(splitIpInfo[4]);
return cityInfo;
} catch (Exception e) {
log.error("Ip2regionUtil getCityInfo error, ip = {}: ", ip, e);
}
return null;
}
@Data
public static class CityInfo {
private String ip;
private String searchIpInfo;
private String country;
private String region;
private String province;
private String city;
private String ISP;
}
}
测试代码
package top.emanjusaka.ip2region;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import top.emanjusaka.ip2region.util.Ip2regionUtil;
@SpringBootTest
class Ip2regionApplicationTests {
@Test
void testIp() {
String ip = "117.61.25.78";
Ip2regionUtil.CityInfo cityInfo = Ip2regionUtil.getCityInfo(ip);
System.out.println("test ip2region");
System.out.println("ip:" + cityInfo.getIp());
System.out.println("country:" + cityInfo.getCountry());
System.out.println("region:" + cityInfo.getRegion());
System.out.println("province:" + cityInfo.getProvince());
System.out.println("city:" + cityInfo.getCity());
System.out.println("isp:" + cityInfo.getISP());
}
}
测试结果:
谦学于心,谷纳万物,静思致远,共筑收获之旅!