整理网友的材料,最后有源码,亲测能解决所有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. NGINX高并发配置

    1.  worker_processes 8; nginx 进程数,建议按照cpu 数目来指定,一般为它的倍数 (如,2个四核的cpu计为8). 2.  worker_cpu_affinity 000 ...

  2. Rabbit mq订阅方式获取消息并可设置持久化

    Rabbit 通过方式获取消息:订阅方式事实上是向queue注冊consumer,通过rpc向queue server发送注冊consumer的消息.rabbitMQ Server在收到消息后,依据消 ...

  3. VB操作EXCEL文件大全

    Private Sub writeToExcel(strTmp1() As String, colTmp1 As Collection)'' Dim tmp1 Dim i1 As Integer, i ...

  4. Maven常用指令

    Maven是通过pom.xml配置好一系列操作,然后通过命令行来进行控制操作的.格式为 mvn 命令 常用命令主要有: mvn 命令 -v:查看maven版本 compile:编译项目 test:测试 ...

  5. JVM内的守护线程Deamon与用户线程User Thread

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561771.html  一:守护线程Daemon 守护线程:Daemon在希腊神话中解作“守护神”,顾名思义就 ...

  6. java HMAC_SHA1加密算法

      java HMAC_SHA1加密算法 CreationTime--2018年7月14日16点46分 Author:Marydon 1.准备工作 import javax.crypto.Mac; i ...

  7. ios判断是否有中文

    //判断是否有中文 -(BOOL)IsChinese:(NSString *)str { ; i< [str length];i++){ int a = [str characterAtInde ...

  8. LLVM和clang

    LLVM编译器架构 LLVM项目是一套工具的集合,它包括模块化.可复用的编译器及一些列工具链技术. LLVM最开始是Low Level Virtual Machine的简称,但现在它并不是传统意义上的 ...

  9. 注意Hibernate4在开发当中的一些改变(转)

    注意Hibernate4在开发当中的一些改变 原文:http://hi.baidu.com/austincao/item/fc9907da3d854e44fa576861 Hibernate4的改动较 ...

  10. Geocoding java调用百度地图API v2.0 图文 实例( 解决102错误)

    如何使用? 第一步:申请ak(即获取密钥),若无百度账号则首先需要注册百度账号. 第二步,拼写发送http请求的url,注意需使用第一步申请的ak. 第三步,接收http请求返回的数据(支持json和 ...