IPUtils.java 3.83 KB
package com.huaheng.control.management.utils;

import lombok.experimental.UtilityClass;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * IP工具类
 */
@UtilityClass
public class IPUtils {

    /**
     * 获取客户端真实IP地址,并将回环地址转换为localhost
     * @param  request HttpServletRequest对象
     * @return         客户端真实IP,回环地址显示为localhost
     */
    public static String getClientIP(HttpServletRequest request) {
        if (request == null) {
            return "unknown";
        }

        String[] headers = {"X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"};

        for (String header : headers) {
            String ip = request.getHeader(header);
            if (isValidIP(ip)) {
                return formatIP(ip.split(",")[0].trim());
            }
        }

        return formatIP(request.getRemoteAddr());
    }

    /**
     * 从当前请求上下文获取客户端IP
     * @return 客户端IP,回环地址显示为localhost
     */
    public static String getClientIP() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                return getClientIP(request);
            }
        } catch (Exception e) {
            // 忽略异常,返回unknown
        }
        return "unknown";
    }

    /**
     * 格式化IP地址,将回环地址转换为localhost
     * @param  ip 原始IP地址
     * @return    格式化后的IP地址
     */
    private static String formatIP(String ip) {
        if (ip == null || ip.isEmpty()) {
            return "unknown";
        }

        // 将IPv6和IPv4回环地址统一转换为localhost
        if ("0:0:0:0:0:0:0:1".equals(ip) || "::1".equals(ip) || "127.0.0.1".equals(ip)) {
            return "localhost";
        }

        return ip;
    }

    /**
     * 获取请求的完整URL,并将回环地址替换为localhost
     * @param  request HttpServletRequest对象
     * @return         完整URL
     */
    public static String getFullURL(HttpServletRequest request) {
        if (request == null) {
            return "unknown";
        }

        StringBuffer requestURL = request.getRequestURL();
        String queryString = request.getQueryString();

        String url = requestURL.toString();

        // 将URL中的回环地址替换为localhost
        url = url.replace("0:0:0:0:0:0:0:1", "localhost").replace("::1", "localhost").replace("127.0.0.1", "localhost");

        if (queryString != null) {
            return url + "?" + queryString;
        }
        return url;
    }

    /**
     * 获取用户代理信息
     * @param  request HttpServletRequest对象
     * @return         User-Agent信息
     */
    public static String getUserAgent(HttpServletRequest request) {
        return request != null ? request.getHeader("User-Agent") : "unknown";
    }

    /**
     * 验证IP地址是否有效(排除回环地址)
     * @param  ip IP地址
     * @return    是否有效
     */
    private static boolean isValidIP(String ip) {
        return ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip) && !"0:0:0:0:0:0:0:1".equals(ip) && !"::1".equals(ip) && !"127.0.0.1".equals(ip);
    }

    /**
     * 判断是否为本地回环地址
     * @param  ip IP地址
     * @return    是否为回环地址
     */
    public static boolean isLoopbackAddress(String ip) {
        return "localhost".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip) || "::1".equals(ip) || "127.0.0.1".equals(ip);
    }
}