top.doudou.common.tool.utils.IpUtils Maven / Gradle / Ivy
package top.doudou.common.tool.utils;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import top.doudou.base.util.FastAssert;
import top.doudou.common.tool.bean.ConvertBeanUtils;
import top.doudou.common.tool.constant.CommonConstant;
import top.doudou.common.tool.constant.RegexConstant;
import top.doudou.common.tool.dto.IpPconlineDto;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.*;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import static top.doudou.common.tool.utils.ServletUtils.getRequest;
/**
* @Description 获取ip
* @Author 傻男人 <[email protected]>
* @Date 2020-09-28 16:10
* @Version V1.0
*/
@Slf4j
public class IpUtils {
private final static String UNKNOWN = "unknown";
/**
* 太平洋网络IP地址查询Web接口
*/
private static final String PCONLINE_URL = "http://whois.pconline.com.cn/ipJson.jsp?json=true";
private static String serverIp;
static {
try {
InetAddress ia = InetAddress.getLocalHost();
serverIp = ia.getHostAddress();
} catch (UnknownHostException e) {
log.error("未知的网络,错误的原因:{}",e.getMessage());
serverIp = CommonConstant.LOCAL_HOST;
}
}
/**
* 获取ip
*
* @return {String}
*/
public String getIpAddr() {
return getIpAddr(getRequest());
}
/**
* 获取ip
*
* @param request HttpServletRequest
* @return {String}
*/
public static String getIpAddr(HttpServletRequest request) {
FastAssert.notNull(request, "HttpServletRequest is null");
String ipAddress = null;
try {
//X-Forwarded-For:Squid 服务代理
ipAddress = request.getHeader("X-Forwarded-For");
if (StringUtils.isBlank(ipAddress) || UNKNOWN.equalsIgnoreCase(ipAddress)) {
//Proxy-Client-IP:apache 服务代理
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isBlank(ipAddress)|| UNKNOWN.equalsIgnoreCase(ipAddress)) {
//WL-Proxy-Client-IP:weblogic 服务代理
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isBlank(ipAddress)|| UNKNOWN.equalsIgnoreCase(ipAddress)) {
//HTTP_CLIENT_IP:有些代理服务器
ipAddress = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isBlank(ipAddress)|| UNKNOWN.equalsIgnoreCase(ipAddress)) {
//X-Real-IP:nginx服务代理
ipAddress = request.getHeader("X-Real-IP");
}
if (StringUtils.isBlank(ipAddress)|| UNKNOWN.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR");
}
//有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP
if (ipAddress != null && ipAddress.length() != 0) {
ipAddress = ipAddress.split(",")[0];
}
//还是不能获取到,最后再通过request.getRemoteAddr();获取
if (StringUtils.isBlank(ipAddress) || UNKNOWN.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
}
if (CommonConstant.LOCAL_IP.equals(ipAddress)) {
ipAddress = getServerIp();
}
} catch (Exception e) {
ipAddress = "";
}
return ipAddress;
}
/**
* 获取服务器的ip地址
*
* @return String
*/
public static String getServerIp() {
return serverIp;
}
/**
* 获取所有的网卡的ip v4地址,key为网卡地址,value为ip地址
*
* @return hash map
*/
public static Map getLocalIPV4() {
Map map = new HashMap<>();
InetAddress ip = null;
try {
Enumeration netInterfaces = NetworkInterface.getNetworkInterfaces();
while (netInterfaces.hasMoreElements()) {
NetworkInterface ni = netInterfaces.nextElement();
Enumeration ips = ni.getInetAddresses();
while (ips.hasMoreElements()) {
ip = ips.nextElement();
if (ip instanceof Inet4Address) {
map.put(ni.getName(), ip.getHostAddress());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
/**
* 获取所有ipv6地址
*
* @return hash map
*/
public static Map getLocalIPV6() {
Map map = new HashMap<>();
InetAddress ip = null;
try {
Enumeration netInterfaces = NetworkInterface.getNetworkInterfaces();
while (netInterfaces.hasMoreElements()) {
NetworkInterface ni = netInterfaces.nextElement();
Enumeration ips = ni.getInetAddresses();
while (ips.hasMoreElements()) {
ip = ips.nextElement();
if (ip instanceof Inet6Address) {
map.put(ni.getName(), ip.getHostAddress());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
/**
* 根据long值获取ip v4地址:xx.xx.xx.xx
*
* @param longIP IP的long表示形式
* @return IP V4 地址
*/
public static String longToIpv4(long longIP) {
final StringBuilder sb = StrUtil.builder();
// 直接右移24位
sb.append((longIP >>> 24));
sb.append(".");
// 将高8位置0,然后右移16位
sb.append(((longIP & 0x00FFFFFF) >>> 16));
sb.append(".");
sb.append(((longIP & 0x0000FFFF) >>> 8));
sb.append(".");
sb.append((longIP & 0x000000FF));
return sb.toString();
}
/**
* 根据ip地址(xxx.xxx.xxx.xxx)计算出long型的数据
*
* @param strIP IP V4 地址
* @return long值
*/
public static long ipv4ToLong(String strIP) {
if(ReUtil.isMatch(RegexConstant.IPV4_PATTERN,strIP)){
long[] ip = new long[4];
// 先找到IP地址字符串中.的位置
int position1 = strIP.indexOf(".");
int position2 = strIP.indexOf(".", position1 + 1);
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];
}
return 0;
}
/**
* 调用太平洋网络IP地址查询Web接口(http://whois.pconline.com.cn/),返回ip、地理位置
* @param ip
* @return
*/
public static IpPconlineDto getIpInfo(String ip){
String url = PCONLINE_URL;
//查指定ip
if(!StringUtils.isEmpty(ip)){
url = PCONLINE_URL+"&ip=" + ip;
}
StringBuilder inputLine = new StringBuilder();
String read;
try {
HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setRequestProperty("Charset", "GBK");
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "GBK"));
while ((read = in.readLine()) != null) {
inputLine.append(read);
}
in.close();
} catch (Exception e) {
e.printStackTrace();
}
return ConvertBeanUtils.convert(inputLine.toString(),IpPconlineDto.class,Charset.forName("UTF-8"));
}
/*
终极大法:java获取不了,就用js来获取
*/
/**
* 直接根据访问者的Request,返回ip、地理位置
* @param request
* @return
*/
public static IpPconlineDto getIpInfoByRequest(HttpServletRequest request){
return getIpInfo(getIpAddr(request));
}
}