实现一:
@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);
}
}