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

查看:179
本文介绍了在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天全站免登陆