
net.apexes.commons.lang.Networks Maven / Gradle / Ivy
/*
* Copyright (c) 2018, apexes.net. All rights reserved.
*
* http://www.apexes.net
*
*/
package net.apexes.commons.lang;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeoutException;
/**
* @author HeDYn
*/
public final class Networks {
private Networks() {
}
/**
* 获取网络时间戳
* @return 返回网络时间戳
*/
public static long networkTimeMillis()
throws NetworkTimeMillisException, InterruptedException, ExecutionException, TimeoutException {
return networkTimeMillis(
new InetSocketAddress("pool.ntp.org", NTPTimeMillis.DEFAULT_PORT),
new InetSocketAddress("ntp.aliyun.com", NTPTimeMillis.DEFAULT_PORT),
new InetSocketAddress("time.windows.com", NTPTimeMillis.DEFAULT_PORT),
new InetSocketAddress("time.apple.com", NTPTimeMillis.DEFAULT_PORT));
}
/**
* 从指定的网络地址获取网络时间戳
* @param addrs NTP服务器地址
* @return 返回网络时间戳结果列表
*/
public static long networkTimeMillis(InetSocketAddress... addrs)
throws NetworkTimeMillisException, InterruptedException, ExecutionException, TimeoutException {
return networkTimeMillis(NTPTimeMillis.DEFAULT_TIMEOUT_MS, addrs);
}
/**
* 从指定的网络地址获取网络时间戳
* @param executor 执行获取时间任务的线程池
* @param addrs NTP服务器地址
* @return 返回网络时间戳
*/
public static long networkTimeMillis(ExecutorService executor, InetSocketAddress... addrs)
throws NetworkTimeMillisException, InterruptedException, ExecutionException, TimeoutException {
return networkTimeMillis(executor, NTPTimeMillis.DEFAULT_TIMEOUT_MS, addrs);
}
/**
* 从指定的网络地址获取网络时间戳
* @param timeoutMs 超时时间,单位ms
* @param addrs NTP服务器地址
* @return 返回网络时间戳
*/
public static long networkTimeMillis(int timeoutMs, InetSocketAddress... addrs)
throws NetworkTimeMillisException, InterruptedException, ExecutionException, TimeoutException {
return NetworkTimeMillis.invoke(timeoutMs, addrs);
}
/**
* 从指定的网络地址获取网络时间戳
* @param executor 执行获取时间任务的线程池
* @param timeoutMs 超时时间,单位ms
* @param addrs NTP服务器地址
* @return 返回网络时间戳
*/
public static long networkTimeMillis(ExecutorService executor, int timeoutMs, InetSocketAddress... addrs)
throws NetworkTimeMillisException, InterruptedException, ExecutionException, TimeoutException {
return NetworkTimeMillis.invoke(executor, timeoutMs, addrs);
}
/**
* 判断指定的异常是否是网络未连接上产生的异常
* @param throwable 要检查的异常
* @return 如果是网络未连接产生的异常就返回 true
*/
public static boolean isNotConnectThrowable(Throwable throwable) {
if (throwable == null) {
return false;
}
if (throwable instanceof java.net.NoRouteToHostException
|| throwable instanceof java.net.UnknownHostException
|| throwable instanceof javax.net.ssl.SSLHandshakeException
|| throwable instanceof java.net.ConnectException) {
return true;
}
Throwable cause = throwable.getCause();
if (cause != null) {
return isNotConnectThrowable(cause);
}
return false;
}
/**
* 返回 {@code application/x-www-form-urlencoded} 字符串,如 key1=value1&key2=value2
*/
public static String forNameValuePair(Iterable> iterable) {
try {
return forNameValuePair(iterable, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
throw Exceptions.rethrow(e);
}
}
/**
* 返回 {@code application/x-www-form-urlencoded} 字符串,如 key1=value1&key2=value2
*/
public static String forNameValuePair(Iterable> iterable, String charset)
throws UnsupportedEncodingException {
Checks.verifyNotNull(iterable, "iterable");
Checks.verifyNotNull(charset, "charset");
StringBuilder sb = new StringBuilder();
for (Map.Entry entry : iterable) {
String key = URLEncoder.encode(entry.getKey(), charset);
String value = URLEncoder.encode(entry.getValue(), charset);
if (sb.length() > 0) {
sb.append('&');
}
sb.append(key);
if (value != null) {
sb.append('=');
sb.append(value);
}
}
return sb.toString();
}
/**
* 获取本机的MAC地址的字符串格式。xx:xx:xx:xx
*/
public static String macString() {
byte[] macBytes = macBytes();
if (macBytes == null) {
return null;
}
StringBuilder buf = new StringBuilder();
for (byte b : macBytes) {
buf.append(Bytes.toHex(b));
buf.append(":");
}
buf.setLength(buf.length() - 1);
return buf.toString();
}
/**
* 获取本机的MAC地址的Long值
*/
public static Long macValue() {
byte[] macBytes = macBytes();
if (macBytes == null) {
return null;
}
byte[] bytes = new byte[8];
System.arraycopy(macBytes, 0, bytes, 2, 6);
return Bytes.bytesToLong(bytes);
}
public static byte[] macBytes() {
try {
Enumeration nics = NetworkInterface.getNetworkInterfaces();
if (nics == null) {
return null;
}
while (nics.hasMoreElements()) {
NetworkInterface ifc = nics.nextElement();
if (!ifc.isLoopback()) {
byte[] data = ifc.getHardwareAddress();
if (data != null && data.length == 6) {
return data;
}
}
}
} catch (java.net.SocketException e) {
// fine, let's take is as signal of not having any interfaces
}
return null;
}
public static InetAddress local() throws SocketException, UnknownHostException {
InetAddress candidateAddress = null;
Enumeration enumeration = NetworkInterface.getNetworkInterfaces();
while (enumeration.hasMoreElements()) {
NetworkInterface netIf = enumeration.nextElement();
for (Enumeration inetAddress = netIf.getInetAddresses(); inetAddress.hasMoreElements();) {
InetAddress next = inetAddress.nextElement();
// 排除回环类型地址
if (!next.isLoopbackAddress()) {
if (next.isSiteLocalAddress()) {
return next;
}
// 若不是site-local地址,记录下该地址当作候选
if (candidateAddress == null) {
candidateAddress = next;
}
}
}
}
return candidateAddress == null ? InetAddress.getLocalHost() : candidateAddress;
}
public static Pair findSiteLocal() throws SocketException {
Enumeration enumeration = NetworkInterface.getNetworkInterfaces();
while (enumeration.hasMoreElements()) {
NetworkInterface netIf = enumeration.nextElement();
for (Enumeration inetAddress = netIf.getInetAddresses(); inetAddress.hasMoreElements();) {
InetAddress next = inetAddress.nextElement();
// 排除回环类型地址
if (next.isLoopbackAddress()) {
continue;
}
if (next.isSiteLocalAddress() && next instanceof Inet4Address) {
return new Pair<>(next, netIf);
}
}
}
return null;
}
public static String url(String host, String path) {
if (host.endsWith("/")) {
if (path.startsWith("/")) {
return host + path.substring(1);
}
} else if (!path.startsWith("/")) {
return host + "/" + path;
}
return host + path;
}
public static HttpURLConnection connect(URL url, SSLSocketFactory socketFactory, HostnameVerifier hostnameVerifier)
throws IOException {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
if (conn instanceof HttpsURLConnection) {
HttpsURLConnection https = (HttpsURLConnection) conn;
if (hostnameVerifier != null) {
https.setHostnameVerifier(hostnameVerifier);
}
if (socketFactory != null) {
https.setSSLSocketFactory(socketFactory);
}
}
return conn;
}
public static HttpURLConnection connectExemptSSL(URL url) throws IOException, KeyManagementException, NoSuchAlgorithmException {
if ("https".equalsIgnoreCase(url.getProtocol())) {
return connect(url, exemptSSLContext().getSocketFactory(), exemptHostnameVerifier());
}
return connect(url, null, null);
}
/**
* 创建一个支持双向认证的SSLContext
*/
public static SSLContext mutualAuthSSLContext(String trustCert, String keyCert, String keyCertPassword)
throws Exception {
KeyManager[] keyManagers = certKeyManagers(keyCert, keyCertPassword);
TrustManager[] trustManagers = certTrustManagers(trustCert);
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(keyManagers, trustManagers, new SecureRandom());
return sslContext;
}
/**
* 创建一个不检查证书的SSLContext
*
* @return 返回一个不检查证书的SSLContext实例
*/
public static SSLContext exemptSSLContext() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, exemptTrustManagers(), new SecureRandom());
return sslContext;
}
/**
* 创建一个不验证的HostnameVerifier
* @return 返回一个不验证的HostnameVerifier实例
*/
public static HostnameVerifier exemptHostnameVerifier() {
return exemptHostnameVerifier;
}
/**
* 使用base64格式的证书创建KeyManager数组
*/
public static KeyManager[] certKeyManagers(String pemCert, String certPassword) throws Exception {
Checks.verifyNotNull(pemCert, "pemCert");
Checks.verifyNotNull(certPassword, "certPassword");
byte[] bytes = Base64.decode(pemCert);
assert bytes != null;
KeyStore keySotre = KeyStore.getInstance("PKCS12");
keySotre.load(new ByteArrayInputStream(bytes), certPassword.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(keySotre, certPassword.toCharArray());
return kmf.getKeyManagers();
}
/**
* 使用base64格式的证书创建TrustManager数组
*/
public static TrustManager[] certTrustManagers(String pemCert) throws Exception {
Checks.verifyNotNull(pemCert, "pemCert");
byte[] bytes = Base64.decode(pemCert);
assert bytes != null;
CertificateFactory factory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(bytes));
String alias = cert.getSubjectX500Principal().getName();
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null);
trustStore.setCertificateEntry(alias, cert);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(trustStore);
return tmf.getTrustManagers();
}
/**
* 创建一个不检查证书的TrustManager[]
*/
public static TrustManager[] exemptTrustManagers() {
return ExemptVerifyTrustManager.trustManagers;
}
/**
* @author HeDYn
*/
private static class ExemptVerifyTrustManager implements X509TrustManager {
static TrustManager[] trustManagers = new TrustManager[]{new ExemptVerifyTrustManager()};
private static final X509Certificate[] _X509S = new X509Certificate[]{};
@Override
public void checkClientTrusted(X509Certificate[] x509s, String s) {
}
@Override
public void checkServerTrusted(X509Certificate[] x509s, String s) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return _X509S;
}
}
/**
* @author HeDYn
*/
private static final HostnameVerifier exemptHostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy