IpUtil 获取客户端真实IP地址和获取服务器ip地址工具类

IpUtil 获取客户端真实IP地址和获取服务器ip地址工具类

java 复制代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;

public class IpUtil {

    private static final Logger logger = LoggerFactory.getLogger(IpUtil.class);

    /**
     * 定义需要依次检测的IP请求头(优先级从高到低)
     */
    private static final List<String> IP_HEADERS = Arrays.asList(
            "X-Forwarded-For",
            "Proxy-Client-IP",
            "WL-Proxy-Client-IP",
            "HTTP_CLIENT_IP",
            "HTTP_X_FORWARDED_FOR",
            "X-Real-IP"
    );

    /**
     * 获取客户端真实IP地址
     *
     * @param request HttpServletRequest请求对象
     * @return 客户端真实IP,获取失败返回默认IP:127.0.0.1
     */
    public static String getIp(HttpServletRequest request) {
        // 1. 非空校验,避免空指针异常
        if (request == null) {
            logger.warn("HttpServletRequest对象为空,无法获取IP");
            return "127.0.0.1";
        }

        // 2. 打印MAC地址(原代码逻辑保留)
        String macAddr = request.getHeader("mac_addr");
        logger.info("客户端MAC地址:{}", macAddr);

        String ip = null;
        // 3. 遍历IP请求头,按优先级获取真实IP
        for (String header : IP_HEADERS) {
            ip = request.getHeader(header);
            // 打印每个请求头的IP值,方便调试
            logger.info("请求头[{}]获取的IP:{}", header, ip);
            // 判断IP是否有效(非空、非unknown)
            if (isValidIp(ip)) {
                break;
            }
        }

        // 4. 所有请求头都无效时,使用原生远程地址
        if (!isValidIp(ip)) {
            ip = request.getRemoteAddr();
            logger.info("使用request.getRemoteAddr()获取IP:{}", ip);
        }

        // 5. 处理多层代理的IP格式:xxx.xxx.xxx.xxx,xxx.xxx.xxx.xxx
        if (ip != null && ip.contains(",")) {
            // 截取第一个有效IP
            ip = ip.split(",")[0].trim();
        }

        // 6. 最终兜底,确保返回非空IP
        return isValidIp(ip) ? ip : "127.0.0.1";
    }

    /**
     * 判断IP字符串是否有效
     * 规则:不为null、长度大于0、不等于unknown(忽略大小写)
     *
     * @param ip 待校验的IP字符串
     * @return 有效返回true,无效返回false
     */
    private static boolean isValidIp(String ip) {
        return ip != null && ip.length() >0 && !"unknown".equalsIgnoreCase(ip);
    }

    /**
     * 获取服务器ip地址
     * @return
     */
    public static String  getLocalIp(){
        try{
            // 获取本机所有网卡
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            // 遍历所有网卡
            while (interfaces.hasMoreElements()){
                NetworkInterface ni = interfaces.nextElement();
                //过滤回环接口、虚拟接口、未启用的接口
                if(ni.isLoopback()||ni.isVirtual()|| !ni.isUp()){
                        continue;
                }
                Enumeration<InetAddress> addresses = ni.getInetAddresses();
                // 遍历当前网卡下所有IP地址
                while (addresses.hasMoreElements()){
                    InetAddress addr = addresses.nextElement();
                    if(!addr.isLoopbackAddress() && addr.getAddress().length==4){
                        return  addr.getHostAddress();
                    }
                }
            }
        }catch (Exception e){
            logger.error("获取本机网卡列表发生异常", e);
        }
        return "127.0.0.1";
    }

   /* public static void main(String[] args) {
        System.out.println(getLocalIp());
    }
*/

}