获取发送请求的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); } }