This article presents a refactored, production-ready utility for performing HTTP GET and POST requests in Java using the standard java.net API—without external depenedncies. The implementation improves upon legacy patterns by eliminating raw iterators, enhancing parameter encoding safety, unifying resource handling, and applying modern Java conventions.
Refactored HTTP Utility Class
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
/**
* Lightweight HTTP client utility supporting GET and POST requests.
* Uses URLConnection with proper encoding, timeouts, and resource management.
*/
public class HttpEndpointClient {
private static final int DEFAULT_CONNECT_TIMEOUT_MS = 5_000;
private static final int DEFAULT_READ_TIMEOUT_MS = 10_000;
private static final String DEFAULT_CONTENT_TYPE = "application/x-www-form-urlencoded";
/**
* Executes a GET request with query parameters from a map.
*
* @param endpoint URL to call
* @param params key-value parameters to encode into the query string
* @param charset character encoding (e.g., "UTF-8")
* @return response body as a string, or empty string on error
*/
public static String get(String endpoint, Map<String, ?> params, String charset) {
String queryString = buildQueryString(params);
String fullUrl = endpoint + (queryString.isEmpty() ? "" : "?" + queryString);
return executeGet(fullUrl, charset);
}
/**
* Executes a GET request with a pre-encoded query string.
*
* @param endpoint URL to call
* @param query encoded query string (e.g., "q=java&lang=en")
* @param charset character encoding
* @return response body as a string
*/
public static String get(String endpoint, String query, String charset) {
String fullUrl = endpoint + (query.isEmpty() ? "" : "?" + query);
return executeGet(fullUrl, charset);
}
private static String executeGet(String urlStr, String charset) {
try {
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
configureConnection(conn, charset);
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream(), charset))) {
return reader.lines().collect(Collectors.joining("\n"));
}
} catch (Exception e) {
System.err.println("GET request failed: " + e.getMessage());
return "";
}
}
/**
* Executes a POST request with form-encoded parameters from a map.
*
* @param endpoint URL to call
* @param params key-value form data
* @param charset encoding for both request and response
* @return response body as a string
*/
public static String post(String endpoint, Map<String, ?> params, String charset) {
String body = buildQueryString(params);
return executePost(endpoint, body, charset);
}
/**
* Executes a POST request with a raw request body.
*
* @param endpoint URL to call
* @param body form-encoded or plain text payload
* @param charset encoding used for writing and reading
* @return response body as a string
*/
public static String post(String endpoint, String body, String charset) {
return executePost(endpoint, body, charset);
}
private static String executePost(String endpoint, String body, String charset) {
try {
URL url = new URL(endpoint);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
configureConnection(conn, charset);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
try (OutputStream os = conn.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(os, charset)) {
writer.write(body);
writer.flush();
}
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream(), charset))) {
return reader.lines().collect(Collectors.joining("\n"));
}
} catch (Exception e) {
System.err.println("POST request failed: " + e.getMessage());
return "";
}
}
private static void configureConnection(HttpURLConnection conn, String charset) {
conn.setRequestProperty("Content-Type", DEFAULT_CONTENT_TYPE + "; charset=" + charset);
conn.setRequestProperty("Accept-Charset", charset);
conn.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT_MS);
conn.setReadTimeout(DEFAULT_READ_TIMEOUT_MS);
conn.setInstanceFollowRedirects(true);
}
private static String buildQueryString(Map<String, ?> params) {
if (params == null || params.isEmpty()) return "";
return params.entrySet().stream()
.filter(entry -> entry.getKey() != null && entry.getValue() != null)
.map(entry -> {
String key = URLEncoder.encode(entry.getKey().toString(), StandardCharsets.UTF_8);
String value = URLEncoder.encode(entry.getValue().toString(), StandardCharsets.UTF_8);
return key + "=" + value;
})
.collect(Collectors.joining("&"));
}
}
Usage Examples
The following demonstrates safe, idiomatic usagee—including proper URL encoding and error resilience:
public class HttpExample {
public static void main(String[] args) {
// Example 1: IP geolocation via GET
String ipLookupUrl = "http://int.dpool.sina.com.cn/iplookup/iplookup.php";
Map<String, String> ipParams = Map.of("format", "json", "ip", "218.4.255.255");
String ipResponse = HttpEndpointClient.get(ipLookupUrl, ipParams, "UTF-8");
System.out.println("IP Lookup Result:\n" + ipResponse);
// Example 2: Address geocoding via POST
String geoUrl = "http://gc.ditu.aliyun.com/geocoding";
Map<String, String> addressParams = Map.of("a", "苏州市");
String geoResponse = HttpEndpointClient.post(geoUrl, addressParams, "UTF-8");
System.out.println("Geocoding Result:\n" + geoResponse);
// Example 3: Raw query string (less common but supported)
String rawQuery = "q=java&limit=5";
String searchResult = HttpEndpointClient.get("https://api.example.com/search", rawQuery, "UTF-8");
System.out.println("Search Result:\n" + searchResult);
}
}
Note: This implementation avoids deprecated practices such as manual Iterator loops, unsafe string concatenation, unchecked casts, and missing URL encoding. All parameters are automatically percent-encoded using URLEncoder, and resources are managed via try-with-resources for guaranteed cleanup.