整理网友的材料,最后有源码,亲测能解决所有java获取IP真实地址的问题

整理的这里:

1、链接1

2、链接2

JSP里,获取客户端的IP地址的方法是:

request.getRemoteAddr()

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

如果使用了反向代理软件,将

http://192.168.1.110:2046/

的URL反向代理为

http://www.javapeixun.com.cn /

的URL时,用

request.getRemoteAddr()
方法获取的IP地址是:127.0.0.1 或 192.168.1.110,而并不是客户端的真实IP。

ISAPI过滤器也会对request对象进行再包装,附加一些WLS要用的头信息。实际的iisforward附加头如下:
WL-Proxy-Client-IP=211.161.1.239
Proxy-Client-IP=211.161.1.239
X-Forwarded-For=211.161.1.239
WL-Proxy-Client-Keysize=
WL-Proxy-Client-Secretkeysize=
X-WebLogic-Request-ClusterInfo=true
X-WebLogic-KeepAliveSecs=30
X-WebLogic-Force-JVMID=-327089098
WL-Proxy-SSL=false

经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。当我们访问

http://www.javapeixun.com.cn /index.jsp/

时,其实并不是我们浏览器真正访问到了服务器上的index.jsp文件,而是先由代理服务器去访问

http://192.168.1.110:2046/index.jsp

,代理服务器再将访问到的结果返回给我们的浏览器,因为是代理服务器去访问index.jsp的,所以index.jsp中通过

request.getRemoteAddr()

的方法获取的IP实际上是代理服务器的地址,并不是客户端的IP地址。

于是可得出获得客户端真实IP地址的方法一:

public String getRemortIP(HttpServletRequest request) {
if (request.getHeader("x-forwarded-for") == null) {
return request.getRemoteAddr();
}
return request.getHeader("x-forwarded-for");
}

可是当我访问

http://www.5a520.cn /index.jsp/

时,返回的IP地址始终是unknown,也并不是如上所示的127.0.0.1 或 192.168.1.110了,而我访问

http://192.168.1.110:2046/index.jsp

时,则能返回客户端的真实IP地址,写了个方法去验证。原因出在了Squid上。squid.conf 的配制文件 forwarded_for 项默认是为on,如果 forwarded_for 设成了 off  则:

X-Forwarded-For: unknown

于是可得出获得客户端真实IP地址的方法二:

public String getIpAddr(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;
}

可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值,究竟哪个才是真正的用户端的真实IP呢?

答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。

如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100用户真实IP为: 192.168.1.110

以上方法还不行的话就采用如下方法:

/**
* 获取当前网络ip
* @param request
* @return
*/
public String getIpAddr(HttpServletRequest request){
String ipAddress = request.getHeader("x-forwarded-for");
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")){
//根据网卡取本机配置的IP
InetAddress inet=null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress= inet.getHostAddress();
}
}
//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15
if(ipAddress.indexOf(",")>0){
ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));
}
}
return ipAddress;
}

Java获取请求客户端的真实IP地址的更多相关文章

  1. 多级反向代理下,Java获取请求客户端的真实IP地址多中方法整合

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

  2. java 获取请求客户端的真实IP地址

    转载自:http://leiyongping88.iteye.com/blog/1545930 用request.getRemoteAddr();方法获取的IP地址是:127.0.0.1或192.16 ...

  3. 服务器受到网络攻击时,如何获取请求客户端的真实 IP?

    网络攻击 前不久公司遭受了一次网络攻击. 早晨刚到公司,就发现登录接口的调用次数飙升,很快就确认是被恶意攻击,让安全部门做网关入口针对对方 IP 加了限制. 并统一对所有的 IP 加了调用的频率限制. ...

  4. 通过HttpservletRequest对象获取客户端的真实IP地址

    这篇文章主要介绍了Java中使用HttpRequest获取用户真实IP地址,使用本文方法可以避免Apache.Squid.nginx等反向代理软件导致的非真实IP地址,需要的朋友可以参考下 在JSP里 ...

  5. php 获取客户端的真实ip地址 通过第三方网站

    <?php include 'simple_html_dom.php'; // 1获取真实IP地址方式 function get_onlineip() { $ch = curl_init('ht ...

  6. TFS应用层服务器获取F5用户的真实IP地址(高可用性)

    当用户数量达到一定级别(例如2千)以上,为保证TFS系统的持续服务,最大程度减少因系统宕机对研发团队的影响,系统管理员一般会考虑应用层和数据库层的高可用性方案. 在应用层的高可用性方案中,目前比较常见 ...

  7. java 获取的是本地的IP地址

    1 public static void main(String[] args) { 2 try { 3 InetAddress address = InetAddress.getLocalHost( ...

  8. 关于nginx反向代理后获取不到客户端的真实ip地址问题

    前段时间在我的网站上用nginx做了一下反向代理,最近发现不能获取客户端ip了,都是拿到的127.0.0.1的本地ip... 通过查资料后,再去看了看我的配置文件,结果发现我没有如下配置: nginx ...

  9. java 获取web登录者的ip地址

    /** * 获取访问用户的客户端IP(适用于公网与局域网). */ public static final String getIpAddr(final HttpServletRequest requ ...

随机推荐

  1. J2EE开发之三种项目架构

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6285069.html 在我们开发项目时,一般都要先划分好哪些是与用户交互的,哪些用来处理请求/数据等等,这些过 ...

  2. vim note write

    Try: :vert sb N which will open a left vertical split (by default, unless you have modified some opt ...

  3. Orabbix监控Oracle 11g

    Orabbix简介说明 orabbix是一个用来监控oracle数据库性能的zabbix插件工具,通过安装在被监控服务器上客户端上收集数据并传给zabbix服务器端,然后通过调用图形显示.具有以下功能 ...

  4. RPC远程调用概念 &amp;&amp; demo实例

    RPC是指远程过程调用,直观说法就是A通过网络调用B的过程方法. 也就是说两台serverA.B,一个应用部署在Aserver上,想要调用Bserver上应用提供的函数/方法,因为不在一个内存空间,不 ...

  5. 理解Scala - 核心规则

    看到这里有几个有意思的 规则,转载于此: Read Eval Print Loop (REPL) REPL在Scala里面指的是直接运行scala.exe进入的交互式命令行模式.广义上讲,也泛指那些在 ...

  6. ubuntu 终端中文显示乱码问题!

    1 Alt+Ctrl+F1 进入第一个终端,发现中文乱码. 2 安装zhcon. sudo apt-get install zhcon 3 输入下面命令,启动zhcon,中文显示正常. zhcon - ...

  7. db_table--Spring Security3.1 最新配置实例

    2011-04-28 这几天学习了一下Spring Security3.1,从官网下载了Spring Security3.1版本进行练习,经过多次尝试才摸清了其中的一些原理.本人不才,希望能帮助大家. ...

  8. 使用requests库发起gbk编码的get请求

    有一个爬虫,查询需要发起get请求,这个网站整个都是gbk编码 如果直接发起请求,是不可以的,因为请求参数q首先用utf8编码转化成bytes,然后将bytes进行URLEncode变为字符串. re ...

  9. 蓝牙进阶之路 (001) - HC-05蓝牙无线模块设置

    USB转串口的有线转接方式,实在太难看了,尤其是寻接头,那是相当的不方便.其它电器厂商都想把是接头做小,做精致,唯独串口接头还是那么庞大,感觉应该换一换了,都已经完全不符合这个时代的审美观了. 于是, ...

  10. resume.c

    resume.c //采用CURLOPT_RESUME_FROM_LARGE 实现文件断点续传功能 #include <stdlib.h> #include <stdio.h> ...