方法一:
public static String getIp(final HttpServletRequest request) {
String ip;
ip = request.getHeader("X-Forword-For");
if (ip == null || ip.trim().equals("") || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.trim().equals("") || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.trim().equals("") || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.trim().equals("") || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.trim().equals("") || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
/* 多个路由时,取第一个非unknown的ip */
if (ip != null && !ip.trim().equals("")) {
if (ip.indexOf(',') > 0) {
ip = ip.substring(0, ip.indexOf(','));
}
return ip;
} else {
return "0.0.0.0";
}
}
其中第4行中的 “X-Forword-For” 为Nginx配置文件中配置,我的Nginx配置中为 X-Forword-For $proxy_add_x_forwarded_for;
方法二:
public static final String _255 = "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
public static final Pattern pattern = Pattern.compile("^(?:" + _255 + "\\.){3}" + _255 + "$");
public static String getIpFromRequest(HttpServletRequest request) {
String ip;
boolean found = false;
if ((ip = request.getHeader("X-Forword-For")) != null) {
StrTokenizer tokenizer = new StrTokenizer(ip, ",");
while (tokenizer.hasNext()) {
ip = tokenizer.nextToken().trim();
if (isIPv4Valid(ip) && !isIPv4Private(ip)) {
found = true;
break;
}else if(isIPv4Valid(ip) && isIPv4Private(ip)){
log.info("###### 存在代理的内部IP");
return ip;
}
}
}
if (!found) {
log.info("###### 无代理内部IP");
ip = request.getRemoteAddr();
}
return ip;
}
public static boolean isIPv4Private(String ip) {
log.info("###### 判断是否内部ip");
long longIp = ip2long(ip);
return (longIp >= ip2long("10.0.0.0") && longIp <= ip2long("10.255.255.255"))
|| (longIp >= ip2long("172.16.0.0") && longIp <= ip2long("172.31.255.255"))
|| longIp >= ip2long("192.168.0.0") && longIp <= ip2long("192.168.255.255");
}
public static boolean isIPv4Valid(String ip) {
return pattern.matcher(ip).matches();
}
/**
* 将127.0.0.1形式的IP地址转换成十进制整数,这里没有进行任何错误处理
*
* @param strIp
* @return
*/
public static long ip2long(final String strIp) {
final long[] ip = new long[4];
final int position1 = strIp.indexOf('.');
final int position2 = strIp.indexOf('.', position1 + 1);
final int position3 = strIp.indexOf('.', position2 + 1);
ip[0] = Long.parseLong(strIp.substring(0, position1));
ip[1] = Long.parseLong(strIp.substring(position1 + 1, position2));
ip[2] = Long.parseLong(strIp.substring(position2 + 1, position3));
ip[3] = Long.parseLong(strIp.substring(position3 + 1));
return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
}
其中第43行中的 "X-Forword-For" 同样为Nginx中配置内容。
方法一和方法二都可以获取真实IP地址。(方法二中参考网上资源整理)
public static String getIp(final HttpServletRequest request) {
String ip;
ip = request.getHeader("X-Forword-For");
if (ip == null || ip.trim().equals("") || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.trim().equals("") || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.trim().equals("") || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.trim().equals("") || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.trim().equals("") || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
/* 多个路由时,取第一个非unknown的ip */
if (ip != null && !ip.trim().equals("")) {
if (ip.indexOf(',') > 0) {
ip = ip.substring(0, ip.indexOf(','));
}
return ip;
} else {
return "0.0.0.0";
}
}
其中第4行中的 “X-Forword-For” 为Nginx配置文件中配置,我的Nginx配置中为 X-Forword-For $proxy_add_x_forwarded_for;
方法二:
public static final String _255 = "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
public static final Pattern pattern = Pattern.compile("^(?:" + _255 + "\\.){3}" + _255 + "$");
public static String getIpFromRequest(HttpServletRequest request) {
String ip;
boolean found = false;
if ((ip = request.getHeader("X-Forword-For")) != null) {
StrTokenizer tokenizer = new StrTokenizer(ip, ",");
while (tokenizer.hasNext()) {
ip = tokenizer.nextToken().trim();
if (isIPv4Valid(ip) && !isIPv4Private(ip)) {
found = true;
break;
}else if(isIPv4Valid(ip) && isIPv4Private(ip)){
log.info("###### 存在代理的内部IP");
return ip;
}
}
}
if (!found) {
log.info("###### 无代理内部IP");
ip = request.getRemoteAddr();
}
return ip;
}
public static boolean isIPv4Private(String ip) {
log.info("###### 判断是否内部ip");
long longIp = ip2long(ip);
return (longIp >= ip2long("10.0.0.0") && longIp <= ip2long("10.255.255.255"))
|| (longIp >= ip2long("172.16.0.0") && longIp <= ip2long("172.31.255.255"))
|| longIp >= ip2long("192.168.0.0") && longIp <= ip2long("192.168.255.255");
}
public static boolean isIPv4Valid(String ip) {
return pattern.matcher(ip).matches();
}
/**
* 将127.0.0.1形式的IP地址转换成十进制整数,这里没有进行任何错误处理
*
* @param strIp
* @return
*/
public static long ip2long(final String strIp) {
final long[] ip = new long[4];
final int position1 = strIp.indexOf('.');
final int position2 = strIp.indexOf('.', position1 + 1);
final int position3 = strIp.indexOf('.', position2 + 1);
ip[0] = Long.parseLong(strIp.substring(0, position1));
ip[1] = Long.parseLong(strIp.substring(position1 + 1, position2));
ip[2] = Long.parseLong(strIp.substring(position2 + 1, position3));
ip[3] = Long.parseLong(strIp.substring(position3 + 1));
return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
}
其中第43行中的 "X-Forword-For" 同样为Nginx中配置内容。
方法一和方法二都可以获取真实IP地址。(方法二中参考网上资源整理)