在 Servlet 中获取真实的客户端 IP [英] Get real client IP in a Servlet

查看:34
本文介绍了在 Servlet 中获取真实的客户端 IP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个简单的问题.我会在 HTTPServlet 中获取真实的客户端 IP.

I'm having some trouble with a simple problem. I would get the real client IP inside an HTTPServlet.

从现在开始我使用:

request.getRemoteAddr()

但现在它返回一个错误的 IP.例如:xxx.xxx.xxx.50 但我的 IP 类似于 xxx.xxx.xxx.159.(在 http://whatismyipaddress.com/ 上查看).

But now it returns a false IP. eg: xxx.xxx.xxx.50 but my IP is something like xxx.xxx.xxx.159. (checked at http://whatismyipaddress.com/).

现在我尝试使用:

request.getHeader("X-Forwarded-For")

它返回NULL.

我还对以下课程进行了调查:

I also took a probe with the following class:

public class IpUtils {

public static final String _255 = "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
public static final Pattern pattern = Pattern.compile("^(?:" + _255 + "\.){3}" + _255 + "$");

public static String longToIpV4(long longIp) {
    int octet3 = (int) ((longIp >> 24) % 256);
    int octet2 = (int) ((longIp >> 16) % 256);
    int octet1 = (int) ((longIp >> 8) % 256);
    int octet0 = (int) ((longIp) % 256);

    return octet3 + "." + octet2 + "." + octet1 + "." + octet0;
}

public static long ipV4ToLong(String ip) {
    String[] octets = ip.split("\.");
    return (Long.parseLong(octets[0]) << 24) + (Integer.parseInt(octets[1]) << 16)
            + (Integer.parseInt(octets[2]) << 8) + Integer.parseInt(octets[3]);
}

public static boolean isIPv4Private(String ip) {
    long longIp = ipV4ToLong(ip);
    return (longIp >= ipV4ToLong("10.0.0.0") && longIp <= ipV4ToLong("10.255.255.255"))
            || (longIp >= ipV4ToLong("172.16.0.0") && longIp <= ipV4ToLong("172.31.255.255"))
            || longIp >= ipV4ToLong("192.168.0.0") && longIp <= ipV4ToLong("192.168.255.255");
}

public static boolean isIPv4Valid(String ip) {
    return pattern.matcher(ip).matches();
}

public static String getIpFromRequest(HttpServletRequest request) {
    String ip;
    boolean found = false;
    if ((ip = request.getHeader("x-forwarded-for")) != null) {
        StringTokenizer tokenizer = new StringTokenizer(ip, ",");
        while (tokenizer.hasMoreTokens()) {
            ip = tokenizer.nextToken().trim();
            if (isIPv4Valid(ip) && !isIPv4Private(ip)) {
                found = true;
                break;
            }
        }
    }

    if (!found) {
        ip = request.getRemoteAddr();
    }

    return ip;
}
}

它还返回了 xxx.xxx.xxx.50 IP.:(

It also returned the xxx.xxx.xxx.50 IP. :(

现在不知道怎么获取真实的客户端IP.如果有人知道解决方案,请回答.

Now I don't know how to get the real client IP. If somebody knows the solution please make an answer.

推荐答案

我想你的问题是你在本地网络的某个地方运行服务器,所以你在那个网络中获得了你的 IP.但是,当您尝试使用发现您的 IP 地址的在线服务时,您的 IP 是您的服务提供商路由器的 IP 或类似的东西.使用 request.getRemoteAddr() 是正确的.这就是这些服务所做的,他们没有其他设施.

I suppose that your problem is that you are running server somewhere in local network, so you get your IP in that network. However when you are trying to use online service that discovers your IP address your IP is the IP of your service provider's router or something like this. Using request.getRemoteAddr() is correct. This is what such services do and they do not have other facilities.

这篇关于在 Servlet 中获取真实的客户端 IP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆