Java通过Request获取用户IP代码实例

本文介绍了如何在Java中通过HttpServletRequest获取用户的真实IP地址,重点在于处理代理服务器情况下的IP获取。代码示例中涉及了"HTTP_X_FORWARDED_FOR"、"X-Forwarded-For"和"X-Real-IP"等请求头,以确保在Nginx等转发服务器场景下能正确获取IP。同时,文章提醒如果请求头未设置相应参数,将可能获取到代理服务的IP而非用户的真实IP。

本着相互交流学习的目的,最近在网上学习和查找了“java如何通过HttpServletRequest获取用户真实请求ip”的相关文章,结合部分大神的示例代码资源,整理出本文章,供大家参考。代码如下:



import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;


/**
 *  测试类
 */
public class TakeIpTest 
{
	
	/**
	 *  ip获取方法
	 */
	public static String getIpAddress(HttpServletRequest request)
	{
		try
		{
			// 获取用户真实的ip地址(有代理时配置文件必须配置才能获取得到)
			String xIp = request.getHeader("X-Real-IP") ;
			if(judgeString(xIp)!=null)
			{
				return judgeString(xIp) ;
			}
			
			// 获取多次代理后的IP字符串值,有值就取第一个(大部分代理第一个ip是用户的真实ip)
			String xFfIp = request.getHeader("X-Forwarded-For") ;
			if (judgeString(xFfIp)!=null)
			{
				String[] strs = xFfIp.split(",") ;
//		        for (String s : strs) 
//		        {
//		            if (judgeString(s)!=null) 
//		            {
//		                return judgeString(Xip) ;
//		            }
//		        }
				if (judgeString(strs[0])!=null) 
	            {
	                return judgeString(strs[0]) ;
	            }
			}
			
			// 获取apache 代理服务器IP
			String pCIp = request.getHeader("Proxy-Client-IP") ;
			if(judgeString(pCIp)!=null)
			{
				return judgeString(pCIp) ;
			}
			
			// 获取weblogic 代理服务器IP
			String wPCIp = request.getHeader("WL-Proxy-Client-IP") ;
			if(judgeString(wPCIp)!=null)
			{
				return judgeString(wPCIp) ;
			}
			
			// 获取http 客户端IP
			String hCIp = request.getHeader("HTTP_CLIENT_IP") ;
			if(judgeString(hCIp)!=null)
			{
				return judgeString(hCIp) ;
			}
			
			// 获取http 代理服务器IP
			String hXFFIp = request.getHeader("HTTP_X_FORWARDED_FOR") ;
			if(judgeString(hXFFIp)!=null)
			{
				return judgeString(hXFFIp) ;
			}
			
			// 获取请求最后一个ip(有代理就是最后一个代理服务ip,没有代理就是用户请求的真实ip)
			String rAIp = request.getRemoteAddr() ;
			if(judgeString(rAIp)!=null)
			{
				return judgeString(rAIp) ;
			}
		} 
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * 字符判断是否符合要求(不为空、不是指定特殊字符、符合ip格式),符合就返回字符,不符合就返回null
	 */	
	public static String judgeString( String str) 
	{
		String nowStr = str.trim() ;
		if(StringUtils.isNotEmpty(nowStr) &&  strJudgeString(nowStr,"unknown,null,undefined, ") && JudgeIpString(nowStr) )
		{
			return nowStr ;
		}
		else
		{
			return null ;
		}
	}

	/**
	 * 特殊字符判断,不分大小写,包含返回false,不包含返回true
	 */	
	public static boolean strJudgeString( String str, String JudgeStr) 
	{
		String[] strs = JudgeStr.split(",") ;
        for (String s : strs) 
        {
            if ((s).equalsIgnoreCase(str)) 
            {
                return false ;
            }
        }
        return true ;
	}

	/**
	 * 判断ip是否符合格式,不符合返回false,符合返回true
	 */	
	public static boolean JudgeIpString( String str) 
	{
		//只判断ip,不判断端口号
		String regex = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\"
				     + ".(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$" ;
		//判断ip和端口号
//		String regex = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\"
//				     + ".(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)"
//				     + ":([0-9]|[1-9]\\d{1,3}|[1-5]\\d{4}|6[0-5]{2}[0-3][0-5])$";
        return str.matches(regex) ;
	}

}

 

其中,获取“HTTP_X_FORWARDED_FOR”、“X-Forwarded-For”、“X-Real-IP” 中的ip,则转发的服务器中的转发请求头Header中必须设置对应参数并赋值上一个请求的ip,这样最后才能拿到ip。以Nginx为例,代码如下:

#本机ip:2.2.2.2 转发到3.3.3.3上去 ,nginx.conf
location / {
            root              html;
            index             index.html;
            proxy_set_header  X-Forwarded-For          $proxy_add_x_forwarded_for;
            proxy_set_header  HTTP_X_FORWARDED_FOR     $remote_addr;
            proxy_set_header  X-Real-IP                $remote_addr;
            proxy_pass        http://3.3.3.3;
        }

参数说明:

 
参数释义示例
X-Real-IPnginx 代理服务器IP         X-Real-IP: 127.0.0.1
X-Forwarded-Forsquid 代理服务器IPX-Forwarded-For: 127.0.0.1, 127.0.0.2, 127.0.0.3, .....
Proxy-Client-IPapache 代理服务器IPProxy-Client-IP: 127.0.0.1
WL-Proxy-Client-IPweblogic 代理服务器IPWL-Proxy-Client-IP: 127.0.0.1
HTTP_CLIENT_IPhttp 客户端IPHTTP_CLIENT_IP: 127.0.0.1
HTTP_X_FORWARDED_FORhttp 代理服务器IPHTTP_X_FORWARDED_FOR: 127.0.0.1

 

 

 

 

 

 

 

注意:

    请求头Header中必须设置对应参数并赋值,这样服务端才能获取到相应参数里的ip,否则单靠HttpServletRequest. getRemoteAddr()获取的ip不一定是用户的真实ip,因为有代理时此函数获取的是最后一个代理服务ip,没有代理时才获取的是用户请求的真实ip;

 

今天分享到此为止,有不足之处望大家留言指出,万分感谢。

最后感谢下列博主的文章给予分享和参考:

https://blog.youkuaiyun.com/Hello_World_QWP/article/details/85407888

 

### Java代码实现获取设备的公网IP地址 在Java中,可以通过多种方法来获取设备的公网IP地址。以下是几种常见的实现方式: #### 方法一:通过HTTP请求外部服务 利用第三方API服务(如`httpbin.org/ip` 或 `api.ipify.org`),可以发送HTTP GET请求并解析返回的结果。 ```java import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class PublicIPAddress { public static void main(String[] args) throws Exception { URL url = new URL("https://api.ipify.org?format=json"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { StringBuilder response = new StringBuilder(); String line; while ((line = in.readLine()) != null) { response.append(line); } System.out.println(response.toString()); // 输出JSON格式的公网IP信息 } } } ``` 此方法依赖于外部服务提供准确的公网IP数据[^4]。 --- #### 方法二:基于HttpServletRequest对象 如果程序运行在一个Web环境中,可以直接从`HttpServletRequest`对象中提取客户端的真实IP地址。这种方法适用于服务器端应用。 ```java import javax.servlet.http.HttpServletRequest; public class IPAddressUtil { public static String getClientIp(HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For"); if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } public static void main(String[] args) { // 此处仅作为示例展示逻辑,实际需注入HttpServletRequest实例 System.out.println(getClientIp(null)); } } ``` 该方法适合用于处理代理环境下的真实IP捕获需求。 --- #### 方法三:使用InetAddress类 虽然`InetAddress.getLocalHost().getHostAddress()`通常只返回局域网内的私有IP地址,但在某些特定场景下也可以尝试调用公共DNS查询接口间接得到公网IP。 注意:这种方式并不推荐直接应用于生产环境,因为其准确性无法完全保障[^3]。 --- ### 总结 最可靠的方式仍然是借助成熟的在线服务完成公网IP检测任务。上述提到的第一种方案即为此目的设计而成,并且已被广泛验证可行性和稳定性[^5]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值