在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr() ,这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。
如果使用了反向代理软件,将http://192.168.1.110:2046/ 的URL反向代理为http://www.xxx.com/ 的URL时,用request.getRemoteAddr() 方法获取的IP地址是:127.0.0.1 或 192.168.1.110 ,而并不是客户端的真实IP。
经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。当我们访问http://www.xxx.com/index.jsp/ 时,其实并不是我们浏览器真正访问到了服务器上的index.jsp文件,而是先由代理服务器去访问http://192.168.1.110:2046/index.jsp ,代理服务器再将访问到的结果返回给我们的浏览器,因为是代理服务器去访问index.jsp的,所以index.jsp中通过request.getRemoteAddr() 的方法获取的IP实际上是代理服务器的地址,并不是客户端的IP地址。
于是可得出获得客户端真实IP地址的方法一:

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

/**
* The Class IpUtils.
*
*/
public abstract class IpUtils {

/**
* Gets the client ip addr.
*
* @param request the request
* @return the client ip addr
*/
public static String getClientIpAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
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.getRemoteAddr();
}
return ip;
}

/**
* Gets the real ips.
*
* @return the real ips
*/
public static List<String> getRealIps() {
List<String> ips = new ArrayList<String>();
String localip = null;// 本地IP,如果没有配置外网IP则返回它
String netip = null;// 外网IP
Enumeration<NetworkInterface> netInterfaces;
try {
netInterfaces = NetworkInterface.getNetworkInterfaces();
} catch (SocketException e) {
return null;
}
InetAddress ip = null;
boolean finded = false;// 是否找到外网IP
while (netInterfaces.hasMoreElements() && !finded) {
NetworkInterface ni = netInterfaces.nextElement();
Enumeration<InetAddress> address = ni.getInetAddresses();
while (address.hasMoreElements()) {
ip = address.nextElement();
if (!ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {// 外网IP
netip = ip.getHostAddress();
ips.add(netip);
finded = true;
break;
} else if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {// 内网IP
localip = ip.getHostAddress();
ips.add(localip);
}
}
}
return ips;
}

/**
* Gets the real ip.
*
* @return the real ip
*/
public static String getRealIp() {
return getRealIps().iterator().next();
}
}

根据Request获取客户端IP 内网IP及外网IP的更多相关文章

  1. iptables 实现centos内网机器访问外网

    环境:一台带外网和内网的机器,另一台只有内网,默认不能上网.两台机器都是centos系统带外网机器的外网ip为 123.221.20.11, 内网ip为 192.168.15.100内网机器的内网ip ...

  2. openvpn实现内网 映射到 外网

    openvpn实现内网 映射到 外网 场景介绍: 机器介绍 本地一台Ubuntu服务器A , 处于内网中 , 无外网IP 外网一台Ubuntu服务器B , 外网地址139.199.4.205 目标 : ...

  3. Request获取客户端IP

    获取客户端的IP地址的方法是:request.getRemoteAddr() ,这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了. ...

  4. 根据Request获取客户端IP

    转自: http://www.cnblogs.com/icerainsoft/p/3584532.html http://www.cnblogs.com/bingya/articles/3134227 ...

  5. 【C#】C#获取本地的内网(局域网)和外网(公网)IP地址的方法

    1.获取本机的IP地址集合: /// <summary> /// 获取本机所有ip地址 /// </summary> /// <param name="netT ...

  6. 通过Request获取客户端的真实IP

    我们在做项目的时候经常需要获取客户端的真实ip去进行判断,为此搜索了相关文章,以下这个讲解的比较明白,直接拿来 https://blog.csdn.net/yin_jw/article/details ...

  7. .NET 获取客户端的操作系统版本、浏览器版本和IP地址

    我们在使用.NET做网站的时候,很多情况下需要需要知道客户端的操作系统版本和浏览器版本,怎样获取客户端的操作系统和浏览器版本呢?我们可以通过分析UserAgent来获取. .NET 获取客户端的操作系 ...

  8. dubbo调用外网接口 注册外网ip到zookeeper 暴露外网ip

    dubbo注册时会通过主机名寻找ip,会将内网ip注册到zookeeper 如果我们调用外网服务器server的话是找不到的 会报如下错误 [DUBBO] client reconnect to 12 ...

  9. frp内网 穿透映射使内网svn可外网访问

    起因 公司svn目前部署在内网服务器上,现在想在家中也可以使用,因此需要外网访问内网的工具 经过 使用过几个产品: utools,一个小巧的windows下的工具,内网映射只是它的一个小功能,支持tc ...

随机推荐

  1. Enable rsh on MAC OS with command line

    1. Enable rsh on macos. 1). os version (10.0) Enabling the "Allow remote login" option tur ...

  2. 【转】javascript变量声明 及作用域

    javascript变量声明提升(hoisting) javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 先看 ...

  3. 在Ubuntu 12.4 下安装 nginx, MySQL, PHP

    LNMP是时下很流行的网站配置,我在配置蝉大师服务器的时候顺带把经验做个分享,蝉大师的网址是:http://www.ddashi.com/ 1.第一步, 跟新apt-get 输入: sudo apt- ...

  4. data process for large scale datasets

    Kmeans:   总体而言,速度(单线程): yael_kmeans > litekmeans ~ vl_kmeans 1.vl_kemans (win10 + matlab 15 + vs1 ...

  5. 问题:https与http有什么区别啊?

    HTTPS(Secure Hypertext Transfer Protocol)安全超文本传输协议  它是一个安全通信通道,它基于HTTP开发,用于在客户计算机和服务器之间交换信息.它使用安全套接字 ...

  6. Chp10 10.7

    <Java语言程序设计>P296 本章是关于对象的思考,主要是在研究面向对象的程序设计时类的设计,作业写得比较杂乱,构造方法时没有严格遵守类的流行设计风格,由于是作业,再加上比较简单,没有 ...

  7. 腾讯优测优分享 | 游戏的UI自动化测试可以这样开展

    腾讯优测是专业的自动化测试平台,提供自动化测试-全面兼容性测试,云真机-远程真机租用,漏洞分析等多维度的测试服务,让测试更简单! 对于目前的两大游戏引擎cocos-2dx.unity3D,其UI自动化 ...

  8. 两个不同的list随机组合到一个List中。

    今天组长给了一个绑定任务,业务需要把一男一女随机的老师绑定到考场. 测试例子入下: package com.test; import java.util.ArrayList; import java. ...

  9. 【转】Alchemy的使用和多项式批量计算的优化

    原文:http://www.cnblogs.com/flash3d/archive/2012/01/30/2332158.html ================================== ...

  10. Delphi常用关键字用法详解

    本文详细介绍了Delphi中常用的各个关键字名称及用法,供大家在编程过程中借鉴参考之用.详情如下: absolute: ? 1 2 3 4 5 6 7 8 9 10 //它使得你能够创建一个新变量, ...