本着相互交流学习的目的,最近在网上学习和查找了“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-IP | nginx 代理服务器IP | X-Real-IP: 127.0.0.1 |
| X-Forwarded-For | squid 代理服务器IP | X-Forwarded-For: 127.0.0.1, 127.0.0.2, 127.0.0.3, ..... |
| Proxy-Client-IP | apache 代理服务器IP | Proxy-Client-IP: 127.0.0.1 |
| WL-Proxy-Client-IP | weblogic 代理服务器IP | WL-Proxy-Client-IP: 127.0.0.1 |
| HTTP_CLIENT_IP | http 客户端IP | HTTP_CLIENT_IP: 127.0.0.1 |
| HTTP_X_FORWARDED_FOR | http 代理服务器IP | HTTP_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中通过HttpServletRequest获取用户的真实IP地址,重点在于处理代理服务器情况下的IP获取。代码示例中涉及了"HTTP_X_FORWARDED_FOR"、"X-Forwarded-For"和"X-Real-IP"等请求头,以确保在Nginx等转发服务器场景下能正确获取IP。同时,文章提醒如果请求头未设置相应参数,将可能获取到代理服务的IP而非用户的真实IP。
1326

被折叠的 条评论
为什么被折叠?



