一步一脚印:Java中获取客户端IP的详细教程
1、工具类
public class IpUtil {
/**
* @description: 获取客户端的IP地址
* @author: lizhiwei
* @param request
* @return IP地址字符串
* @date: 2024/1/8 10:26
**/
public static String getClientIp(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip != null) {
// 处理多个IP的情况,获取第一个非未知的IP
ip = ip.split(",")[0].trim();
} else {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
// 获取本机真实IP
try {
ip = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
// IP地址获取失败
ip = "unknown";
}
}
}
return ip;
}
}
2、controller
@GetMapping("/getUserIp")
public BaseResponse<String> getIp(HttpServletRequest request) {
String clientIp = IpUtil.getClientIp(request);
log.info("用户ip是::{}", clientIp);
return ResultUtils.success(clientIp);
}
3、代码原理解析
1、public static String getClientIp(HttpServletRequest request) {
//这是一个静态方法的声明,意味着它可以在不创建类的实例的情况下被调用。方法返回一个字符串,表示客户端的IP地址。方法接收一个HttpServletRequest对象作为参数,这个对象代表了当前的HTTP请求。
2、String ip = request.getHeader("X-Forwarded-For");
//这一行尝试从HTTP请求头中获取名为X-Forwarded-For的值。X-Forwarded-For是一个标准的HTTP请求头,通常由代理服务器(如负载均衡器、CDN等)设置,用于转发原始请求者的IP地址。当一个请求经过代理时,代理服务器会在X-Forwarded-For头中追加该请求的原始IP地址。(代理ip也可以拿到)
3、 if (ip != null) {
// 处理多个IP的情况,获取第一个非未知的IP
ip = ip.split(",")[0].trim();
} else {
ip = request.getHeader("Proxy-Client-IP");
}
//这段代码首先检查X-Forwarded-For头是否不为空。如果不为空,可能包含了由逗号分隔的多个IP地址(当请求经过多个代理时会发生这种情况)。此时,代码取第一个IP地址作为客户端的IP。如果X-Forwarded-For为空,代码接着尝试获取Proxy-Client-IP头,这也是一种常见的代理服务器使用的头部。
4、 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
//这一行检查如果ip仍然是空的、长度为0,或者是字符串"unknown",则尝试从请求头WL-Proxy-Client-IP中获取IP地址。WL-Proxy-Client-IP是WebLogic服务器使用的头部,用于同样的目的。
5、 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
}
//类似地,如果ip还是未知,代码会尝试从X-Real-IP头获取IP地址。X-Real-IP通常被一些代理服务器和负载均衡器用来转发原始的IP地址。
6、 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
// 获取本机真实IP
try {
ip = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
// IP地址获取失败
ip = "unknown";
}
}
}
//如果前面的所有步骤都未能获取到IP地址,最后使用request.getRemoteAddr()方法获取发起请求的IP地址。这通常是直接与服务器连接的客户端的IP地址。如果这个地址是本地回环地址(即127.0.0.1或0:0:0:0:0:0:0:1),则尝试获取本机的真实IP地址。这里使用了InetAddress.getLocalHost().getHostAddress()方法。如果无法获取本机地址(如因为未知的主机异常),则将IP设为"unknown"。
7、HttpServletRequest是Java Servlet API中的一个接口,代表客户端发起的一个HTTP请求。当一个客户端(如Web浏览器)向服务器发送请求时,Servlet容器(如Tomcat)会创建一个HttpServletRequest对象,并将其传递给适当的Servlet处理。这个对象包含了所有关于该HTTP请求的信息,比如请求头、参数、URL、HTTP方法等。在Spring Boot应用中,你可以在控制器(Controller)的方法中使用HttpServletRequest来获取这些信息。
4、总结
以上代码均由ChatGPT生成并解析,现在的AI太强大了,你需要一个简单的功能,基本上很快就能把你的问题解决,君子性非异也,擅假于物也。