🔍🎩 Java中的魔法侦探:轻松寻找客户端IP的奇幻之旅

欢迎来到Java的奇妙世界,一个充满代码、笑声和一点点魔法的地方!今天,我们将一起踏上一场探寻客户端IP地址的欢快旅程。戴上你的思维帽,拿起你的编程魔杖,让我们开启这场充满乐趣的冒险!

1、神奇而古怪的工具类

首先,让我们迎接我们的主角------IpUtil,一个有着超能力的Java类,它比侦探福尔摩斯还要厉害!它能在一堆复杂的HTTP请求中找到IP地址,就像是在沙滩上找到那颗特别的沙粒。

java 复制代码
public class IpUtil {


    /**
     * @description: 获取客户端的IP地址
     * @author: lizhiwei
     * @param request
     * @return IP地址字符串
     * @date: 2024/1/8 10:26
    **/
    public static String getClientIp(HttpServletRequest request) {
        // 尝试从HTTP请求的"X-Forwarded-For"头部获取IP地址。
        // "X-Forwarded-For"头通常由代理服务器设置,包含了原始请求的IP地址。
        String ip = request.getHeader("X-Forwarded-For");

        if (ip != null) {
            // 如果"X-Forwarded-For"头包含多个IP地址(通常由于多级代理造成),则取第一个非未知的IP地址。
            ip = ip.split(",")[0].trim();
        } else {
            // 如果"X-Forwarded-For"头不存在,尝试从"Proxy-Client-IP"头获取IP地址。
            // "Proxy-Client-IP"头也是由某些代理服务器设置的。
            ip = request.getHeader("Proxy-Client-IP");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            // 如果"Proxy-Client-IP"头不可用,尝试从"WL-Proxy-Client-IP"头获取IP地址。
            // "WL-Proxy-Client-IP"是WebLogic服务器设置的类似头部。
            ip = request.getHeader("WL-Proxy-Client-IP");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            // 如果"WL-Proxy-Client-IP"头也不可用,尝试从"X-Real-IP"头获取IP地址。
            // "X-Real-IP"头通常被用来记录原始的客户端IP地址。
            ip = request.getHeader("X-Real-IP");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            // 如果以上所有方法都失败,使用request.getRemoteAddr()获取发起请求的客户端IP地址。
            // 这通常是直接连接到服务器的客户端IP。
            ip = request.getRemoteAddr();
            if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
                // 如果获取到的IP是本地回环地址,尝试获取本机的真实IP地址。
                try {
                    ip = InetAddress.getLocalHost().getHostAddress();
                } catch (UnknownHostException e) {
                    // 如果本机IP地址获取失败,将IP地址设置为"unknown"。
                    ip = "unknown";
                }
            }
        }

        return ip; // 返回获取到的IP地址。
    }
}

2、勇敢的控制器

但是,哪怕是最伟大的侦探也需要一个可靠的助手。在我们的故事里,这个角色由controller扮演。他就像是魔法界的电话接线员,一旦有人需要寻找IP,他就迅速将呼叫转给我们的超级侦探IpUtil

java 复制代码
@GetMapping("/getUserIp")
    public BaseResponse<String> getIp(HttpServletRequest request) {
        String clientIp = IpUtil.getClientIp(request);
        log.info("用户ip是::{}", clientIp);
        return ResultUtils.success(clientIp);
    }

3、代码原理的幽默解密

现在,就像是掀开魔术师的帽子,揭秘里面的兔子一样,我们来看看代码背后的秘密。这不仅仅是代码,这是一场编程魔法表演!

  • X光视力启动 :我们的英雄首先使用X-Forwarded-For来寻找IP,就像是使用超级显微镜观察细菌。
  • 多重身份大揭秘:如果IP地址试图使用伪装技巧(比如藏在一串地址中),别担心,我们的侦探能识破它们的伎俩,只抓取第一个!
  • 深入敌后:如果上面的方法不奏效,我们的英雄就会变换战术,尝试其他的秘密通

道,比如Proxy-Client-IPWL-Proxy-Client-IP。这就像是在玩一场"抓迷藏"的游戏,IP地址藏得再好,也逃不过我们的侦探。

  • 最终绝技:本地侦测 :如果所有的技巧都失败了,我们的超级侦探IpUtil就会使用它的终极绝技------getRemoteAddr()。这就像是超级英雄的最后一招,直接透视到请求的核心,揭露真相!
  • 意外转折:本地回环探秘 :有时候,最难找的IP地址就藏在"家里"(也就是本地地址)。这时,我们的英雄会展示他的侦探才能,调用InetAddress.getLocalHost().getHostAddress(),就像是在自己家里找遗失的钥匙一样!
java 复制代码
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、总结:编程的魔法世界

这就是我们的编程魔法表演!一个充满惊喜、挑战和幽默的旅程。记住,每当你在键盘上敲下代码,你就是在施展魔法,每一行代码都是一种咒语,每一个函数都是一次魔法冒险。

在这个故事中,我们不仅学会了如何使用Java找到客户端IP,还体验了编程的乐趣和魔力。所以下次当你遇到编程难题时,别忘了,你有超级英雄IpUtil和他的忠实助手controller,以及一点编程魔法在你身边!君子性非异也,擅假于物也。

相关推荐
是真的小外套37 分钟前
第十五章:XXE漏洞攻防与其他漏洞全解析
后端·计算机网络·php
ybwycx2 小时前
SpringBoot下获取resources目录下文件的常用方法
java·spring boot·后端
小陈工2 小时前
Python Web开发入门(十一):RESTful API设计原则与最佳实践——让你的API既优雅又好用
开发语言·前端·人工智能·后端·python·安全·restful
小阳哥AI工具3 小时前
Seedance 2.0使用真人参考图生成视频的方法
后端
IeE1QQ3GT3 小时前
使用ASP.NET Abstractions增强ASP.NET应用程序的可测试性
后端·asp.net
Full Stack Developme3 小时前
SpringBoot多线程池配置
spring boot·后端·firefox
sxhcwgcy5 小时前
SpringBoot 使用 spring.profiles.active 来区分不同环境配置
spring boot·后端·spring
稻草猫.7 小时前
Spring事务操作全解析
java·数据库·后端·spring
希望永不加班8 小时前
SpringBoot 整合 MongoDB
java·spring boot·后端·mongodb·spring
Lzh编程小栈8 小时前
数据结构与算法之队列深度解析:循环队列+C 语言硬核实现 + 面试考点全梳理
c语言·开发语言·汇编·数据结构·后端·算法·面试