NetUtils 是一個提供網路相關功能的工具類別。此類別設計為靜態工具類別,提供多種網路操作方法,包括 HTTP/HTTPS 請求、IP 位址處理、Socket 連線檢查等功能,特別適合在 Web 應用程式中使用。
// 從 HttpServletRequest 取得客戶端 IP
HttpServletRequest request = ...;
String clientIp = NetUtils.getClientIpAddress(request);
// 取得伺服器主機名稱
String hostName = NetUtils.getHostName();
// 取得伺服器 IP 位址
String serverIp = NetUtils.getHostIpAddr();
// 發送 HTTP GET 請求
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Bearer token123");
HttpResponse<String> response = NetUtils.invokeHttpGet("http://api.example.com", headers);
// 發送 HTTPS GET 請求
HttpResponse<String> secureResponse = NetUtils.invokeHttpsGet("https://api.example.com", headers);
// 準備請求參數
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
Map<String, String> body = new HashMap<>();
body.put("key", "value");
// 發送 HTTP POST 請求
HttpResponse<String> response = NetUtils.invokeHttpPost(
"http://api.example.com",
headers,
body
);
// 發送 HTTPS POST 請求
HttpResponse<String> secureResponse = NetUtils.invokeHttpsPost(
"https://api.example.com",
headers,
body
);
// 取得指定的 URL 參數
List<String> paramNames = Arrays.asList("id", "name");
Map<String, String> params = NetUtils.getRequestValueFromVarNames(request, paramNames);
// 取得所有請求標頭
Map<String, Object> headers = NetUtils.getRequestHeaderAllValues(request);
// 取得請求主體參數
Map<String, Object> bodyParams = NetUtils.getRequestBodyAllValues(request);
// 檢查目標主機和連接埠是否可連線
String host = "example.com";
int port = 80;
int timeoutSeconds = 5;
boolean isConnected = NetUtils.checkSocket(host, port, timeoutSeconds);
// 判斷是否為 Ajax 請求
boolean isAjax = NetUtils.isAjaxRequest(request);
在開發環境中,可以使用內建的信任管理器略過 SSL 憑證驗證:
// 在 HTTPS 請求時自動套用
NetUtilsWebClientModel model = new NetUtilsWebClientModel();
model.setIsSSL(true);
// 設定連線超時
HttpClient httpClient = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build();
用於封裝完整的網路請求參數:
NetUtilsWebClientModel model = new NetUtilsWebClientModel();
model.setUrl("https://api.example.com");
model.setIsSSL(true);
model.setIsGetMethod(false);
// 設定標頭
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
model.setMapHeader(headers);
// 設定表單資料
Map<String, String> formData = new HashMap<>();
formData.put("key", "value");
model.setFormData(formData);
// 執行請求
HttpResponse<String> response = NetUtils.invokeWebService(model);
// 使用自訂信任管理器
TrustManager[] trustManagers = NetUtils.getTrustManagers();
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManagers, new SecureRandom());
// 設定 HTTPS 連線
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
以下測試範例示範 NetUtils 的常見測試策略:
@Test
void testGetClientIpAddress() {
MockHttpServletRequest req = new MockHttpServletRequest();
req.addHeader("X-Forwarded-For", "203.0.113.1");
String ip = NetUtils.getClientIpAddress(req);
assertEquals("203.0.113.1", ip);
}
@Test
void testCheckSocket() {
// 使用常見的開放埠或模擬環境進行測試
boolean reachable = NetUtils.checkSocket("example.com", 80, 5);
// 無法保證對外網路的穩定性,建議在 CI 使用 Mock 或內部測試伺服器
assertNotNull(reachable);
}
@Test
void testInvokeHttpGetWithMock() throws Exception {
// 建議使用 WireMock 或 Mockito 模擬外部 API
// 此處示意:驗證當 HttpClient 回傳時,方法能正確回傳 HttpResponse
// 測試時請在隔離環境模擬 HTTP 回應
}
package tw.lewishome.webapp.base.utility.common;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.URI;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.Builder;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
/**
* NetUtils 是一個實用程式類,提供各種與網路相關的輔助方法。
*
* 功能包括:
* <ul>
* <li>從 HttpServletRequest 中擷取客戶端 IP 位址,並考慮代理程式標頭。</li>
* <li>偵測 Ajax 請求。</li>
* <li>檢查與主機和連接埠的連線。</li>
* <li>從 HttpServletRequest 中擷取參數值。</li>
* <li>取得伺服器主機名稱和 IP 位址。</li>
* <li>傳送帶有自訂標頭和表單資料的 HTTP/HTTPS GET 和 POST 請求。</li>
* <li>繞過 HTTPS 請求的 SSL 憑證驗證(用於開發/測試目的)。</li>
* </ul>
*
* 包含一個內部靜態類別 {@code NetUtilsWebClientModel},用於封裝 Web 用戶端請求資料。
*
* <b>注意:</b>停用 SSL 憑證驗證不安全,不應在生產環境中使用。
*
* @author lewis
* @version 1.0
*/
@Slf4j
public class NetUtils {
/** Private constructor to prevent instantiation */
private NetUtils() {
throw new IllegalStateException("This is a utility class and cannot be instantiated");
}
/**
* HTTP HEADERS
**/
private static final String[] HEADERS_TO_TRY = { "X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP",
"HTTP_X_FORWARDED_FOR", "HTTP_X_FORWARDED", "HTTP_X_CLUSTER_CLIENT_IP", "HTTP_CLIENT_IP",
"HTTP_FORWARDED_FOR", "HTTP_FORWARDED", "HTTP_VIA", "REMOTE_ADDR" };
/**
* 取得 Http Request 的 IP Address
*
* @param request HttpServletRequest
* @return String IP 位址
*/
public static String getClientIpAddress(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
String unknownString = "unknown";
if (StringUtils.isBlank(ip) || unknownString.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isBlank(ip) || unknownString.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isBlank(ip) || unknownString.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isBlank(ip) || unknownString.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isBlank(ip) || unknownString.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
if (StringUtils.isBlank(ip) || unknownString.equalsIgnoreCase(ip)) {
for (String header : HEADERS_TO_TRY) {
ip = request.getHeader(header);
if (StringUtils.isNotBlank(ip) && !unknownString.equalsIgnoreCase(ip)) {
return ip;
}
}
ip = request.getRemoteAddr();
}
return ip;
}
/**
* 判斷是否為 Ajax 請求
*
* @param request HttpServletRequest
* @return boolean 是否為 Ajax
*/
public static boolean isAjaxRequest(HttpServletRequest request) {
return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"))
|| "XMLHttpRequest".equals(request.getAttribute("X-Requested-With"));
}
/**
* 檢查 Socket 連線 (host, port)
*
* @param node IP 位址
* @param port 連接埠
* @param timeout 嘗試時間(秒)
* @return boolean 是否連線成功
*/
public static boolean checkSocket(String node, int port, int timeout) {
try (Socket socket = new Socket()) {
SocketAddress socketAddress = new InetSocketAddress(node, port);
socket.connect(socketAddress, timeout * 1000);
if (socket.isConnected()) {
return true;
}
} catch (IOException e) {
return false;
}
return false;
}
/**
* 從 Http Request 中取得指定 URL 參數(變數)的內容
*
* @param request HttpServletRequest
* @param parameters 變數名稱清單 (URL 參數)
* @return Map 變數名稱與內容(找不到變數則為 null)
*/
public static Map<String, String> getRequestValueFromVarNames(HttpServletRequest request, List<String> parameters) {
Map<String, String> rtnValidMap = new HashMap<>();
for (String parameter : parameters) {
rtnValidMap.put(parameter.trim(), request.getParameter(parameter.trim()));
}
return rtnValidMap;
}
/**
* 從 Http Request 中取得指定 body 參數(變數)的內容
*
* @param request HttpServletRequest
* @return Map 變數名稱與內容(找不到變數則為 null)
* @throws IOException IOException 當讀取請求主體時發生錯誤
*/
@SuppressWarnings("unchecked")
public static Map<String, Object> getRequestBodyAllValues(HttpServletRequest request) throws IOException {
Map<String, Object> mapBodyValues = new HashMap<>();
StringBuilder requestBody = new StringBuilder();
try (BufferedReader reader = request.getReader()) {
String line;
while ((line = reader.readLine()) != null) {
requestBody.append(line);
}
}
String bodyString = requestBody.toString();
ObjectMapper objectMapper = new ObjectMapper();
try {
mapBodyValues = objectMapper.readValue(bodyString, Map.class);
} catch (IOException ex) {
System.err.println("Could not parse request body as JSON");
}
return mapBodyValues;
}
/**
* 從 Http Request 中取得所有參數(變數)的內容
*
* @param request HttpServletRequest
* @return Map 變數名稱與內容(找不到變數則為 null)
*/
public static Map<String, Object> getRequestHeaderAllValues(HttpServletRequest request) {
Map<String, Object> mapHeaderValues = new HashMap<>();
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
mapHeaderValues.put(headerName, request.getHeader(headerName));
}
return mapHeaderValues;
}
/**
* 取得主機名稱 (Server Name)
*
* @return String 主機名稱
*/
public static String getHostName() {
String hostname = "Unknown";
try {
InetAddress hostAddr = InetAddress.getLocalHost();
hostname = hostAddr.getHostName();
} catch (UnknownHostException ex) {
log.error("無法取得主機名稱");
}
return hostname;
}
/**
* 取得主機 IP (Server IP)
*
* @return String 主機 IP
*/
public static String getHostIpAddr() {
String hostIpAddr = "Unknown";
try {
InetAddress hostAddr = InetAddress.getLocalHost();
hostIpAddr = hostAddr.getHostName();
} catch (UnknownHostException ex) {
log.error("無法取得主機名稱");
}
return hostIpAddr;
}
/**
* 發送 HTTP GET 請求
*
* @param url 請求網址
* @param mapHeader 標頭參數
* @return HttpResponse 回應物件
*/
public static HttpResponse<String> invokeHttpGet(String url, Map<String, String> mapHeader) {
NetUtilsWebClientModel webClientModel = new NetUtilsWebClientModel();
webClientModel.setUrl(url);
webClientModel.setIsSSL(false);
webClientModel.setIsGetMethod(true);
webClientModel.setMapHeader(mapHeader);
return invokeWebService(webClientModel);
}
/**
* 發送 HTTPS GET 請求
*
* @param url 請求網址
* @param mapHeader 標頭參數
* @return HttpResponse 回應物件
*/
public static HttpResponse<String> invokeHttpsGet(String url, Map<String, String> mapHeader) {
NetUtilsWebClientModel webClientModel = new NetUtilsWebClientModel();
webClientModel.setUrl(url);
webClientModel.setIsSSL(true);
webClientModel.setIsGetMethod(true);
webClientModel.setMapHeader(mapHeader);
return invokeWebService(webClientModel);
}
/**
* invoke Http Post request
*
* @param url URL
* @param mapHeader Header Param
* @param mapBody mapBody
* @return HttpResponse HttpResponse
*/
public static HttpResponse<String> invokeHttpPost(String url, Map<String, String> mapHeader,
Map<String, String> mapBody) {
NetUtilsWebClientModel webClientModel = new NetUtilsWebClientModel();
webClientModel.setUrl(url);
webClientModel.setIsSSL(false);
webClientModel.setIsGetMethod(false);
webClientModel.setMapHeader(mapHeader);
webClientModel.setFormData(mapBody);
return invokeWebService(webClientModel);
}
/**
* invoke Https Post request
*
* @param url URL
* @param mapHeader Header Param
* @param mapBody mapBody
* @return HttpResponse HttpResponse
*/
public static HttpResponse<String> invokeHttpsPost(String url, Map<String, String> mapHeader,
Map<String, String> mapBody) {
NetUtilsWebClientModel webClientModel = new NetUtilsWebClientModel();
webClientModel.setUrl(url);
webClientModel.setIsSSL(true);
webClientModel.setIsGetMethod(false);
webClientModel.setMapHeader(mapHeader);
webClientModel.setFormData(mapBody);
return invokeWebService(webClientModel);
}
/**
* invoke WebService (Http/https) request
*
* @param webClientModel webClientModel
* @return HttpResponse HttpResponse
*/
public static HttpResponse<String> invokeWebService(NetUtilsWebClientModel webClientModel) {
String url = webClientModel.getUrl();
Boolean isSSL = webClientModel.getIsSSL();
Boolean isGetMethod = webClientModel.getIsGetMethod();
Map<String, String> formData = webClientModel.getFormData();
Map<String, String> mapHeader = webClientModel.getMapHeader();
// Create a trust manager that does not validate certificate chains
String formDataString = "";
if (formData != null && formData.size() > 0) {
formDataString = getFormDataAsString(formData);
}
TrustManager[] trustAllCerts = getTrustManagers();
try {
// Install the all-trusting trust manager
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
// Now you can access an https URL without having the certificate in the
// trust store URL
Builder builder = null;
if (Boolean.TRUE.equals(isGetMethod)) {
builder = HttpRequest.newBuilder().uri(new URI(url)).GET();
} else {
if (StringUtils.isBlank(formDataString)) {
builder = HttpRequest.newBuilder().uri(new URI(url)).POST(HttpRequest.BodyPublishers.noBody());
} else {
builder = HttpRequest.newBuilder().uri(new URI(url))
.POST(HttpRequest.BodyPublishers.ofString(formDataString));
}
}
for (Map.Entry<String, String> entry : mapHeader.entrySet()) {
builder.setHeader(entry.getKey(), entry.getValue());
}
HttpClient httpClient = null;
if (Boolean.TRUE.equals(isSSL)) {
httpClient = HttpClient.newBuilder()
// .connectTimeout(Duration.ofMillis(<timeoutInSeconds> * 1000))
.connectTimeout(Duration.ofMillis(10 * 1000))
// SSL context 'sslContext' initialized as earlier
.sslContext(sslContext)
// .sslParameters(parameters) // ssl parameters if overridden
.build();
} else {
httpClient = HttpClient.newHttpClient();
}
builder.setHeader("Content-Type", "application/application/json");
HttpRequest requestBuilder = builder.build();
return httpClient.send(requestBuilder, HttpResponse.BodyHandlers.ofString());
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
/**
* Create a trust manager that does not validate certificate chains
*
* @return
*/
private static TrustManager[] getTrustManagers() {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
} };
return trustAllCerts;
}
/**
* @param formData Http Form Data
* @return String String
*/
private static String getFormDataAsString(Map<String, String> formData) {
StringBuilder formBodyBuilder = new StringBuilder();
for (Map.Entry<String, String> singleEntry : formData.entrySet()) {
if (formBodyBuilder.length() > 0) {
formBodyBuilder.append("&");
}
formBodyBuilder.append(URLEncoder.encode(singleEntry.getKey(), StandardCharsets.UTF_8));
formBodyBuilder.append("=");
formBodyBuilder.append(URLEncoder.encode(singleEntry.getValue(), StandardCharsets.UTF_8));
}
return formBodyBuilder.toString();
}
/**
* <pre>
* 執行 WebClient 時的資料 Model
* </pre>
*
* @author Lewis
*/
/**
* <pre>
* NetUtilsWebClientModel 是用於處理網路請求的資料模型類別。
* 包含以下主要屬性:
* - URL:網路服務的網址
* - SSL 設定:是否使用 HTTPS
* - 請求方法:GET 或 POST
* - 標頭資訊:請求標頭參數
* - 表單資料:請求主體參數
* - JSON 資料:JSON 格式的請求資料
* - 上傳檔案:位元組陣列格式的上傳檔案
* </pre>
*/
@Data
public static class NetUtilsWebClientModel implements Serializable {
/**
* Fix for javadoc warning :
* use of default constructor, which does not provide a comment
* Constructs a new NetUtilsWebClientModel instance.
* This is the default constructor, implicitly provided by the compiler
* if no other constructors are defined.
*/
public NetUtilsWebClientModel() {
// Constructor body (can be empty)
}
/** serialVersionUID */
private static final long serialVersionUID = 1L;
/** web service URL */
private String url = "";
/** web service is SSL (https) */
private Boolean isSSL = false;
/** web service method is Get (else Post) */
private Boolean isGetMethod = true;
/** Header info Map */
private Map<String, String> mapHeader = new HashMap<>();
/** Body info Map */
private Map<String, String> formData = new HashMap<>();
/** Body info Map */
private String requestJsonData = "";
/** Upload File Data (Byte Array) */
private Byte[] uploadData = null;
}
}
package tw.lewishome.webapp.base.utility.common;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;
import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.http.HttpResponse;
import java.util.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
public class NetUtilsTest {
@Test
@DisplayName("getClientIpAddress should return X-Forwarded-For if present")
void testGetClientIpAddress_XForwardedFor() {
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getHeader("X-Forwarded-For")).thenReturn("1.2.3.4");
assertEquals("1.2.3.4", NetUtils.getClientIpAddress(request));
}
@Test
@DisplayName("getClientIpAddress should fallback to Proxy-Client-IP")
void testGetClientIpAddress_ProxyClientIp() {
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getHeader("X-Forwarded-For")).thenReturn(null);
when(request.getHeader("Proxy-Client-IP")).thenReturn("5.6.7.8");
assertEquals("5.6.7.8", NetUtils.getClientIpAddress(request));
}
@Test
@DisplayName("getClientIpAddress should fallback to WL-Proxy-Client-IP")
void testGetClientIpAddress_WLProxyClientIp() {
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getHeader("X-Forwarded-For")).thenReturn(null);
when(request.getHeader("Proxy-Client-IP")).thenReturn(null);
when(request.getHeader("WL-Proxy-Client-IP")).thenReturn("9.10.11.12");
assertEquals("9.10.11.12", NetUtils.getClientIpAddress(request));
}
@Test
@DisplayName("getClientIpAddress should fallback to HTTP_CLIENT_IP")
void testGetClientIpAddress_HTTP_CLIENT_IP() {
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getHeader("X-Forwarded-For")).thenReturn(null);
when(request.getHeader("Proxy-Client-IP")).thenReturn(null);
when(request.getHeader("WL-Proxy-Client-IP")).thenReturn(null);
when(request.getHeader("HTTP_CLIENT_IP")).thenReturn("13.14.15.16");
assertEquals("13.14.15.16", NetUtils.getClientIpAddress(request));
}
@Test
@DisplayName("getClientIpAddress should fallback to HTTP_X_FORWARDED_FOR")
void testGetClientIpAddress_HTTP_X_FORWARDED_FOR() {
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getHeader("X-Forwarded-For")).thenReturn(null);
when(request.getHeader("Proxy-Client-IP")).thenReturn(null);
when(request.getHeader("WL-Proxy-Client-IP")).thenReturn(null);
when(request.getHeader("HTTP_CLIENT_IP")).thenReturn(null);
when(request.getHeader("HTTP_X_FORWARDED_FOR")).thenReturn("17.18.19.20");
assertEquals("17.18.19.20", NetUtils.getClientIpAddress(request));
}
@Test
@DisplayName("getClientIpAddress should fallback to getRemoteAddr")
void testGetClientIpAddress_RemoteAddr() {
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getHeader(anyString())).thenReturn(null);
when(request.getRemoteAddr()).thenReturn("21.22.23.24");
assertEquals("21.22.23.24", NetUtils.getClientIpAddress(request));
}
@Test
@DisplayName("isAjaxRequest should return true for XMLHttpRequest header")
void testIsAjaxRequest_Header() {
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getHeader("X-Requested-With")).thenReturn("XMLHttpRequest");
assertTrue(NetUtils.isAjaxRequest(request));
}
@Test
@DisplayName("isAjaxRequest should return true for XMLHttpRequest attribute")
void testIsAjaxRequest_Attribute() {
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getHeader("X-Requested-With")).thenReturn(null);
when(request.getAttribute("X-Requested-With")).thenReturn("XMLHttpRequest");
assertTrue(NetUtils.isAjaxRequest(request));
}
@Test
@DisplayName("isAjaxRequest should return false if not Ajax")
void testIsAjaxRequest_False() {
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getHeader("X-Requested-With")).thenReturn(null);
when(request.getAttribute("X-Requested-With")).thenReturn(null);
assertFalse(NetUtils.isAjaxRequest(request));
}
@Test
@DisplayName("getRequestValueFromVarNames should return correct map")
void testGetRequestValueFromVarNames() {
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getParameter("foo")).thenReturn("bar");
when(request.getParameter("baz")).thenReturn("qux");
List<String> params = Arrays.asList("foo", "baz");
Map<String, String> result = NetUtils.getRequestValueFromVarNames(request, params);
assertEquals(2, result.size());
assertEquals("bar", result.get("foo"));
assertEquals("qux", result.get("baz"));
}
@Test
@DisplayName("getHostName should return a non-null string")
void testGetHostName() {
String hostName = NetUtils.getHostName();
assertNotNull(hostName);
assertFalse(hostName.isEmpty());
}
@Test
@DisplayName("getHostIpAddr should return a non-null string")
void testGetHostIpAddr() {
String hostIp = NetUtils.getHostIpAddr();
assertNotNull(hostIp);
assertFalse(hostIp.isEmpty());
}
@Test
@DisplayName("checkSocket should return false for invalid host")
void testCheckSocket_InvalidHost() {
assertFalse(NetUtils.checkSocket("256.256.256.256", 80, 1));
}
/**
* @throws IOException IOException
*/
@Test
@DisplayName("checkSocket should return false for closed port")
void testCheckSocket_ClosedPort() throws IOException {
// 127.0.0.1:9 is usually closed (discard protocol)
assertFalse(NetUtils.checkSocket("127.0.0.1", 9, 1));
}
// The following tests for HTTP methods are smoke tests (not real HTTP calls)
// because actual HTTP calls require network and a running server.
// These tests just check that the methods do not throw and return null (since
// no server).
@Test
@DisplayName("invokeHttpGet should return null for invalid URL")
void testInvokeHttpGet_InvalidUrl() {
HttpResponse<String> response = NetUtils.invokeHttpGet("http://localhost:9999/notfound",
Collections.emptyMap());
assertNull(response);
}
@Test
@DisplayName("invokeHttpsGet should return null for invalid URL")
void testInvokeHttpsGet_InvalidUrl() {
HttpResponse<String> response = NetUtils.invokeHttpsGet("https://localhost:9999/notfound",
Collections.emptyMap());
assertNull(response);
}
@Test
@DisplayName("invokeHttpPost should return null for invalid URL")
void testInvokeHttpPost_InvalidUrl() {
HttpResponse<String> response = NetUtils.invokeHttpPost("http://localhost:9999/notfound",
Collections.emptyMap(), Collections.emptyMap());
assertNull(response);
}
@Test
@DisplayName("invokeHttpsPost should return null for invalid URL")
void testInvokeHttpsPost_InvalidUrl() {
HttpResponse<String> response = NetUtils.invokeHttpsPost("https://localhost:9999/notfound",
Collections.emptyMap(), Collections.emptyMap());
assertNull(response);
}
}