前言:
前几天拉取公司最新代码,发现无法启动项目启动之后登陆之后前端无法跳转页面,然后经过分析,发现请求被拦截器拦截,压根没进网关。于是我进一步发现问题出现在公司项目做的许可证的验证的时候失败了。抛出一个空指针异常。
后来发现公司的许可证生成是根据IP的mac地址来做处理的,然后发现采用的是hutool工具包5.6.6版本,用来获取当前的mac地址。于是出现了上述的问题的思考。
问题解析:
经过一系列操作,和分析。发现问题出在hutool包的版本原因,为了找到为啥出现当前问题,于是我进一步分析之前使用的4.5.10版本和现在的5.6.6版本的区别。
因为获取mac地址是要首先获取到ip地址,假如获取到的ip地址没有网卡,就无法读取到mac地址,会抛出空指针异常。
//当前代码的作用是获取到当前主机的mac地址
String mac = NetworkInterface.getByInetAddress(inetAddress).getHardwareAddress();
复制代码
这个时候可以得出,问题出现在获取到的LocalHost上。
于是我们查看不同版本的获取localhost的的方法上
//4.5.10
public static InetAddress getLocalhost() {
InetAddress candidateAddress = null;
NetworkInterface iface;
InetAddress inetAddr;
try {
for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) {
iface = ifaces.nextElement();
for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
inetAddr = inetAddrs.nextElement();
if (false == inetAddr.isLoopbackAddress()) {
if (inetAddr.isSiteLocalAddress()) {
return inetAddr;
} else if (null == candidateAddress) {
// 非site-local地址做为候选地址返回
candidateAddress = inetAddr;
}
}
}
}
} catch (SocketException e) {
// ignore socket exception, and return null;
}
if (null == candidateAddress) {
try {
candidateAddress = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
// ignore
}
}
return candidateAddress;
}
复制代码
//5.6.6
public static InetAddress getLocalhost() {
final LinkedHashSet<InetAddress> localAddressList = localAddressList(address -> {
// 非loopback地址,指127.*.*.*的地址
return false == address.isLoopbackAddress()
// 非地区本地地址,指10.0.0.0 ~ 10.255.255.255、172.16.0.0 ~ 172.31.255.255、192.168.0.0 ~ 192.168.255.255
&& false == address.isSiteLocalAddress()
// 需为IPV4地址
&& address instanceof Inet4Address;
});
if (CollUtil.isNotEmpty(localAddressList)) {
return CollUtil.get(localAddressList, 0);
}
try {
return InetAddress.getLocalHost();
} catch (UnknownHostException e) {
// ignore
}
return null;
}
复制代码
仔细查看上述代码可以发现问题所在,address.isSiteLocalAddress()的处理有所不同。
老版本是本地区地址,而新版本不允许为本地区地址,假如不满足条件就会返回我们的主角: InetAddress.getLocalHost();因为在家所以,我们的网卡地址很不幸的属于本地区本地地址192.168网段,于是返回的是InetAddress.getLocalHost();
于是考虑,问题可能出现在系统的层次,俺采用的是mac系统,jdk1.8 。 于是经过询问,发现mac好像都会出现当前问题,而win不会出现,于是在网上看到了别人写的linux上也出现过上述情况。
问题是: mac和linux系统在使用jdk1.8下的该方法,获取到的地址都是127.0.0.1,而win获取到的地址是正常的内网ip地址。
因为当前方法获取的ip地址是ping主机名获取的ip。而我们ping的主机名,因为在在host文件里面没找到当前主机名的对应的ip地址,于是直接获取的是127.0.0.1
解决办法 :
- 修改host文件,这个问题好像linux系统都会出现,但是更改host文件也有局限性只适合固定ip,不适合ip多变的情况。
- 用代码直接获取en0的ip,可以直接采用上面的hutool的代码即可。




近期评论