🔍🎩 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,以及一点编程魔法在你身边!君子性非异也,擅假于物也。

相关推荐
闲猫14 分钟前
go orm GORM
开发语言·后端·golang
丁卯40435 分钟前
Go语言中使用viper绑定结构体和yaml文件信息时,标签的使用
服务器·后端·golang
bing_1584 小时前
简单工厂模式 (Simple Factory Pattern) 在Spring Boot 中的应用
spring boot·后端·简单工厂模式
天上掉下来个程小白5 小时前
案例-14.文件上传-简介
数据库·spring boot·后端·mybatis·状态模式
Asthenia04125 小时前
基于Jackson注解的JSON工具封装与Redis集成实战
后端
编程星空6 小时前
css主题色修改后会多出一个css吗?css怎么定义变量?
开发语言·后端·rust
程序员侠客行6 小时前
Spring事务原理 二
java·后端·spring
dmy7 小时前
docker 快速构建开发环境
后端·docker·容器
sjsjsbbsbsn7 小时前
Spring Boot定时任务原理
java·spring boot·后端
计算机毕设指导68 小时前
基于Springboot学生宿舍水电信息管理系统【附源码】
java·spring boot·后端·mysql·spring·tomcat·maven