获取发送请求的ip

实现一:
@Slf4j
public class IpUtils {
    /**
     * 获取发请求的ip
     *
     * @return
     */
    public static String getLocalIP() {
        InetAddress addr = null;
        String ipAddrStr = "";
        try {
            // 获取本地ip
            addr = InetAddress.getLocalHost();
            // 将本地ip数组通过.进行拼装
            byte[] ipAddr = addr.getAddress();
            for (int i = 0; i < ipAddr.length; i++) {
                if (i > 0) {
                    ipAddrStr += ".";
                }
                ipAddrStr += Integer.toString(Integer.valueOf(ipAddr[i]) & 0xFF);
            }
            return ipAddrStr;
        } catch (UnknownHostException e) {
            // 记录异常日志
            log.error("获取本地Ip异常:", e);
            return ipAddrStr;
        }
    }
}

 


实现二:
import com.google.common.net.InetAddresses;
import com.google.common.primitives.Ints;
import lombok.experimental.UtilityClass;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;

/**
 * InetAddress工具类,基于Guava的InetAddresses.
 * <p>
 * 主要包含int, String/IPV4String, InetAdress/Inet4Address之间的互相转换
 * 先将字符串传换为byte[]再用InetAddress.getByAddress(byte[]),避免了InetAddress.getByName(ip)可能引起的DNS访问.
 * InetAddress与String的转换其实消耗不小,如果是有限的地址,建议进行缓存.
 *
 * @author せいうはん
 */
@UtilityClass
public class IPUtils {

    /**
     * 从InetAddress转化到int, 传输和存储时, 用int代表InetAddress是最小的开销.
     * <p>
     * InetAddress可以是IPV4或IPV6,都会转成IPV4.
     *
     * @see com.google.common.net.InetAddresses#coerceToInteger(InetAddress)
     */
    public static int toInt(InetAddress address) {
        return InetAddresses.coerceToInteger(address);
    }

    /**
     * InetAddress转换为String.
     * <p>
     * InetAddress可以是IPV4或IPV6. 其中IPV4直接调用getHostAddress()
     *
     * @see com.google.common.net.InetAddresses#toAddrString(InetAddress)
     */
    public static String toIpString(InetAddress address) {
        return InetAddresses.toAddrString(address);
    }

    /**
     * 从int转换为Inet4Address(仅支持IPV4)
     */
    public static Inet4Address fromInt(int address) {
        return InetAddresses.fromInteger(address);
    }

    /**
     * 从String转换为InetAddress.
     * <p>
     * IpString可以是ipv4 或 ipv6 string, 但不可以是域名.
     * <p>
     * 先字符串传换为byte[]再调getByAddress(byte[]),避免了调用getByName(ip)可能引起的DNS访问.
     */
    public static InetAddress fromIpString(String address) {
        return InetAddresses.forString(address);
    }

    /**
     * 从IPv4String转换为InetAddress.
     * <p>
     * IpString如果确定ipv4, 使用本方法减少字符分析消耗 .
     * <p>
     * 先字符串传换为byte[]再调getByAddress(byte[]),避免了调用getByName(ip)可能引起的DNS访问.
     */
    public static Inet4Address fromIpv4String(String address) {
        byte[] bytes = ip4StringToBytes(address);
        if (bytes == null) {
            return null;
        } else {
            try {
                return (Inet4Address) Inet4Address.getByAddress(bytes);
            } catch (UnknownHostException e) {
                throw new AssertionError(e);
            }
        }
    }

    /**
     * int转换到IPV4 String, from Netty NetUtil
     */
    public static String intToIpv4String(int i) {
        return String.valueOf((i >> 24) & 0xff) + '.' + (i >> 16 & 0xff) + '.' +
            ((i >> 8) & 0xff) + '.' + (i & 0xff);
    }

    /**
     * Ipv4 String 转换到int
     */
    public static int ipv4StringToInt(String ipv4Str) {
        byte[] byteAddress = ip4StringToBytes(ipv4Str);
        if (byteAddress == null) {
            return 0;
        } else {
            return Ints.fromByteArray(byteAddress);
        }
    }

    /**
     * Ipv4 String 转换到byte[]
     */
    private static byte[] ip4StringToBytes(String ipv4Str) {
        if (ipv4Str == null) {
            return null;
        }

        List<String> it = MoreStringUtils.split(ipv4Str, '.', 4);
        if (it.size() != 4) {
            return null;
        }

        byte[] byteAddress = new byte[4];
        for (int i = 0; i < 4; i++) {
            int tempInt = Integer.parseInt(it.get(i));
            if (tempInt > 255) {
                return null;
            }
            byteAddress[i] = (byte) tempInt;
        }
        return byteAddress;
    }
}


import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
import com.google.common.base.Utf8;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 尽量使用Common Lang StringUtils, 基本覆盖了所有类库的StringUtils
 * <p>
 * 本类仅补充少量额外方法, 尤其是针对char的运算
 * 1. split char/chars
 * 2. 针对char的replace first/last, startWith,endWith 等
 *
 * @author せいうはん
 * @version 1.0.0, 2018-03-06 16:39
 * @since 1.0.0, 2018-03-06 16:39
 */
@UtilityClass
public class MoreStringUtils {

    /**
     * 高性能的Split,针对char的分隔符号,比JDK String自带的高效.
     * <p>
     * copy from Commons Lange 3.5 StringUtils 并做优化
     *
     * @see #split(String, char, int)
     */
    public static List<String> split(final String str, final char separatorChar) {
        return split(str, separatorChar, 10);
    }

    /**
     * 高性能的Split,针对char的分隔符号,比JDK String自带的高效.
     * <p>
     * copy from Commons Lange 3.5 StringUtils, 做如下优化:
     * <p>
     * 1. 最后不做数组转换,直接返回List.
     * <p>
     * 2. 可设定List初始大小.
     * <p>
     * 3. preserveAllTokens 取默认值false
     *
     * @param expectParts 预估分割后的List大小,初始化数据更精准
     * @return 如果为null返回null, 如果为""返回空数组
     */
    public static List<String> split(final String str, final char separatorChar, int expectParts) {
        if (str == null) {
            return null;
        }

        final int len = str.length();
        if (len == 0) {
            return Collections.emptyList();
        }

        final List<String> list = new ArrayList<>(expectParts);
        int i = 0;
        int start = 0;
        boolean match = false;
        while (i < len) {
            if (str.charAt(i) == separatorChar) {
                if (match) {
                    list.add(str.substring(start, i));
                    match = false;
                }
                start = ++i;
                continue;
            }
            match = true;
            i++;
        }
        if (match) {
            list.add(str.substring(start, i));
        }
        return list;
    }

    /**
     * 使用多个可选的char作为分割符, 还可以设置omitEmptyStrings,trimResults等配置
     * <p>
     * 设置后的Splitter进行重用,不要每次创建
     *
     * @param separatorChars 比如Unix/Windows的路径分割符 "/\\"
     * @see com.google.common.base.Splitter
     */
    public static Splitter charsSplitter(final String separatorChars) {
        return Splitter.on(CharMatcher.anyOf(separatorChars));
    }

    ////////// 其他 char 相关 ///////////

    /**
     * String 有replace(char,char),但缺少单独replace first/last的
     */
    public static String replaceFirst(String s, char sub, char with) {
        if (s == null) {
            return null;
        }
        int index = s.indexOf(sub);
        if (index == -1) {
            return s;
        }
        char[] str = s.toCharArray();
        str[index] = with;
        return new String(str);
    }

    /**
     * String 有replace(char,char)替换全部char,但缺少单独replace first/last
     */
    public static String replaceLast(String s, char sub, char with) {
        if (s == null) {
            return null;
        }

        int index = s.lastIndexOf(sub);
        if (index == -1) {
            return s;
        }
        char[] str = s.toCharArray();
        str[index] = with;
        return new String(str);
    }

    /**
     * 判断字符串是否以字母开头
     * <p>
     * 如果字符串为Null或空,返回false
     */
    public static boolean startWith(CharSequence s, char c) {
        return !StringUtils.isEmpty(s) && s.charAt(0) == c;
    }

    /**
     * 判断字符串是否以字母结尾
     * <p>
     * 如果字符串为Null或空,返回false
     */
    public static boolean endWith(CharSequence s, char c) {
        return !StringUtils.isEmpty(s) && s.charAt(s.length() - 1) == c;
    }

    /**
     * 如果结尾字符为c, 去除掉该字符.
     */
    public static String removeEnd(final String s, final char c) {
        if (endWith(s, c)) {
            return s.substring(0, s.length() - 1);
        }
        return s;
    }

    ///////////// 其他 ////////////

    /**
     * 计算字符串被UTF8编码后的字节数 via guava
     *
     * @see Utf8#encodedLength(CharSequence)
     */
    public static int utf8EncodedLength(CharSequence sequence) {
        if (StringUtils.isEmpty(sequence)) {
            return 0;
        }
        return Utf8.encodedLength(sequence);
    }
}

 

posted @ 2018-07-12 11:57  舞羊  阅读(492)  评论(0编辑  收藏  举报