在进行测试自动化时,通常需要知道当前计算机的名称,以提示另一台计算机连接到它,特别是在并行运行测试的情况下。 本周,我试图对服务器进行测试,以使其连接回在从属测试计算机上运行的WireMock服务器。
堆栈溢出的标准响应是使用以下模式来获取网络地址。 在我的版本中,如果我们无法解析名称,则假设我们正在VPN上的开发人员便携式计算机上运行,因此所有测试都在同一台计算机上运行。 (因此localhost)
String hostName = "localhost";
try {
InetAddress addr = InetAddress.getLocalHost();
String suggestedName = addr.getCanonicalHostName();
// Rough test for IP address, if IP address assume a local lookup
// on VPN
if (!suggestedName.matches("(\\d{1,3}\\.?){4}") && !suggestedName.contains(":")) {
hostName = suggestedName;
}
} catch (UnknownHostException ex) {
}
System.out.println(hostName);
问题来了,我们必须信任本地计算机设置,例如/ etc / hostname,这可能导致无法从另一台计算机访问的网络名称。 为了解决这个问题,我编写了以下代码,以在可用的网络接口上工作,以查找可用于与本机对话的可远程寻址的网络地址名称。 (我可以使用IP地址,但很难记住它们,尤其是在我们朝IPv6迈进的过程中)
String hostName = stream(wrap(NetworkInterface::getNetworkInterfaces).get())
// Only alllow interfaces that are functioning
.filter(wrap(NetworkInterface::isUp))
// Flat map to any bound addresses
.flatMap(n -> stream(n.getInetAddresses()))
// Fiter out any local addresses
.filter(ia -> !ia.isAnyLocalAddress() && !ia.isLinkLocalAddress() && !ia.isLoopbackAddress())
// Map to a name
.map(InetAddress::getCanonicalHostName)
// Ignore if we just got an IP back
.filter(suggestedName -> !suggestedName.matches("(\\d{1,3}\\.?){4}")
&& !suggestedName.contains(":"))
.findFirst()
// In my case default to localhost
.orElse("localhost");
System.out.println(hostName);
您可能会注意到那里使用了一些支持方法来整理代码,如果您感兴趣的话,这里是必需的支持方法。
@FunctionalInterface
public interface ThrowingPredicate<T, E extends Exception>{
boolean test(T t) throws E;
}
@FunctionalInterface
public interface ThrowingSupplier<T, E extends Exception>{
T get() throws E;
}
public static <T, E extends Exception> Predicate<T> wrap(ThrowingPredicate<T, E> th) {
return t -> {
try {
return th.test(t);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
};
}
public static <T, E extends Exception> Supplier<T> wrap(ThrowingSupplier<T, E> th) {
return () -> {
try {
return th.get();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
};
}
// http://stackoverflow.com/a/23276455
public static <T> Stream<T> stream(Enumeration<T> e) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(
new Iterator<T>() {
public T next() {
return e.nextElement();
}
public boolean hasNext() {
return e.hasMoreElements();
}
},
Spliterator.ORDERED), false);
}
翻译自: https://www.javacodegeeks.com/2016/06/getting-name-someone-connect-back-server.html