在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。

经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的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地址的方法一:

  1. publicif) == nullreturnreturn);
  2. }

可是当我访问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地址的方法二:

  1. public);
  2. ifnull || .equalsIgnoreCase(ip)) {
  3. );
  4. ifnull || .equalsIgnoreCase(ip)) {
  5. );
  6. ifnull || .equalsIgnoreCase(ip)) {
  7. return   }

可是,如果通过了多级反向代理的话,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

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

  1. /**
  2. * 获取当前网络ip
  3. * @param request
  4. * @return
  5. */
  6. public String getIpAddr(HttpServletRequest request){
  7. String ipAddress = request.getHeader("x-forwarded-for");
  8. if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
  9. ipAddress = request.getHeader("Proxy-Client-IP");
  10. }
  11. if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
  12. ipAddress = request.getHeader("WL-Proxy-Client-IP");
  13. }
  14. if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
  15. ipAddress = request.getRemoteAddr();
  16. if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")){
  17. //根据网卡取本机配置的IP
  18. InetAddress inet=null;
  19. try {
  20. inet = InetAddress.getLocalHost();
  21. } catch (UnknownHostException e) {
  22. e.printStackTrace();
  23. }
  24. ipAddress= inet.getHostAddress();
  25. }
  26. }
  27. //对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
  28. if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15
  29. if(ipAddress.indexOf(",")>0){
  30. ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));
  31. }
  32. }
  33. return ipAddress;
  34. }

以上内容均来自网络。鄙人只是对其整合。望对大家帮助!

多级反向代理下,Java获取请求客户端的真实IP地址多中方法整合的更多相关文章

  1. Java获取请求客户端的真实IP地址

    整理网友的材料,最后有源码,亲测能解决所有java获取IP真实地址的问题 整理的这里: 1.链接1 2.链接2 JSP里,获取客户端的IP地址的方法是: request.getRemoteAddr() ...

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

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

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

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

  4. nginx反向代理下没有获取到正确的clientIP问题发散

    问题背景: 在使用nginx服务器NginxA 来反向代理服务 WebAPIA,WebAPIA中要获取ClientIP,结果获取到的IP为NginxA的, 于是引出了以下的一连串概念... 首先使用X ...

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

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

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

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

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

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

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

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

  9. Nginx反向代理下IIS获取真实IP

    1. iis 如果放在反向代理后面,日志里的c-ip是反向代理服务器的ip,不是真正用户的ip,想要记录用户的ip要做两件事. 一.在反向代理设置X-Forwarded-For段,以下为nginx下的 ...

随机推荐

  1. nodepad++快捷键收集

    Notepad++ 快捷键 大全Ctrl+C 复制Ctrl+X 剪切Ctrl+V 粘贴Ctrl+Z 撤消Ctrl+Y 恢复Ctrl+A 全选Ctrl+F 键查找对话框启动Ctrl+H 查找/替换对话框 ...

  2. 东大OJ-5到100000000之间的回文质数

    1217: VIJOS-P1042 时间限制: 0 Sec  内存限制: 128 MB 提交: 78  解决: 29 [提交][状态][讨论版] 题目描述         有一天,雄霸传授本人风神腿法 ...

  3. PHP与MySQL

    这周学习了PHP与MySQL的搭接下面来给大家分享一下: 1.账号注册,论坛发帖... 思路:通过form表单提交到PHP页面,PHP页面往MySQL中插入数据: 2.账号登陆 思路:form提交数据 ...

  4. 美发屋App-业余爱好

    出于个人爱好, 自行设计了一款APP,由于时间有限,APP目前只做了3天,现大四,急求一份实习工作,月薪3K左右即可! 软件UI设计到编码,全部又我一人完成,所以工作量比较大 底部采用·Fragmen ...

  5. ps打造逼真印章效果

    新建500*500px--->路径工具 最后通过 通道扣取选取,填充白色,即可

  6. 长串英文数字强制折行解决办法css

    overflow: hidden; white-space: normal; word-warp: break-word; word-break: break-all;/*Only work in I ...

  7. Question2Answer安装

    Question2Answer安装 Question2Answer的安装过程很简单,只需要几分钟的时间你就可以有一个强大的问答系统. 安装要求 Web服务器(比如Apache) PHP 4.3 或更高 ...

  8. mybatis学习(一) mybatis框架的特性

    mybatis 的源代码地址是https://github.com/mybatis/mybatis-3/ 以及相关文档 All the information i get from http://ww ...

  9. 关于在Eclipse中运行java程序报出:The project:XXXX which is referenced by the classpath10

    1.work_space名称与project是否一样,如果是一样的可能会导致错误. 2.project所在的文件夹中的.mymetadata文件中定义的project-module名称是否与proje ...

  10. 怎么给我的Office文档加密

    很多的用户朋友都可以熟练的使用office中的Word.Excel和PowerPoint文档,但大家对Office文档加密方式了解的并不多.Advanced Office Password Recov ...