java获取ip地址示例
发布时间:2021-12-25 07:04:22
如果使用了反向代理软件,将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地址的方法一:
public String getRemortIP(HttpServletRequest request) {
if (request.getHeader("x-forwarded-for") == null) {
return request.getRemoteAddr();
}
return request.getHeader("x-forwarded-for");
}
可是当我访问http://www.xxx.com/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
猜你喜欢
- 目录springboot autoconfig的一些实验SpringBoot autoconfig部分注解说明SpringBoot auto
- 下面给大家分享一小段代码给大家介绍C# 输出字符串到文本文件中,具体代码如下所示: public class WriteHelp
- 1. 定义TreeMap的排序方法使用Comparator对象作为参数需要注意的是:排序方法是针对键的,而不是值的。如果想针对值,需要更麻烦
- Java停止线程的逻辑(协同、通知)在Java程序中,我们想要停止一个线程可以通过interrupt方法进行停止。但是当我们调用interr
- 前言:回顾之前的微信公众号配置和消息处理的内容,我们已经掌握了如何配置服务器与微信公众号建立连接,也掌握了通过消息管理的方式,对用户的信息进
- 本文介绍的是关于Mybatis中用OGNL表达式处理动态sql的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍:常用的Mybat
- 一. 思路今天接到个小任务,让把json文件转换成excel文件,按照列展开.思路:既然json已经都已经是现成的,那直接将jso
- 本文实例实现文件上传的进度显示,我们先看看都有哪些问题我们要解决。1 上传数据的处理进度跟踪2 进度数据在用户页面的显示就这么2个问题,第一
- 本文讲述了Java递归运行的机制:递归的微观解。分享给大家供大家参考,具体如下:前言:在java递归基础与递归的宏观语意和java链表的天然
- monaco editor创建//创建和设置值if (!this.monacoEditor) { this.monacoEdit
- 摘要:其实两种方法归结起来看还是一种,都是利用Thread的构造器进行创建,区别就是一种是无参的,一种是有参的。一、继承Thread线程类:
- 在开发中,我们经常会使用IO操作,例如创建,删除文件等操作。在项目中这样的需求也较多,我们也会经常对这些操作进行编
- IDEA maven没有dependenciesIDEA导入新项目没有dependencies跟plugins如图:解决办法网上方法很多,重
- 前言本文主要给大家介绍的是关于obix协议在java中的配置和使用,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。什么是
- StringString类是不可变类,即一旦一个String对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁。这个
- Mybatis-Spring当我们使用mybatis和spring整合后为什么下面的代码可以运行?一个问题:我就写了个mapper接口为什么
- 按照官方文档进行的配置:快速开始|mybatis-plus引入依赖:<!-- 引入mybatisPlus --> &
- static :静态常量,静态方法,静态代码块静态变量: 静态变量属于类的,使用类名来访问,非静态变量是属于对象的,"必须&quo
- 写在前面从Java 1.0开始,引入java.io包;到Java 1.4再扩展了java.nio包;再到java 1.7又添加了新的流类,使
- 目录事件最基本的用法理解路由事件WPF中使用路由事件升级了传统应用开发中的事件,在WPF中使用路由事件能更好的处理事件相关的逻辑,我们从这篇