Apache Commons IO 的 FileUtils 雖然功能強大,但預設並不支援直接從 URL 讀取字串內容。本文提供一個實用的擴充方法,結合 IOUtils 實現從 HTTP/HTTPS URL 直接讀取文字內容,並支援指定字元編碼與 POST 請求參數傳遞。
以下兩個靜態方法分別提供無編碼指定(預設平台編碼)與指定編碼的版本:
/**
* 從 URL 讀取內容並轉為字串(使用預設編碼)
* @param source 目標 URL
* @return URL 回應的字串內容
* @throws IOException 發生 I/O 錯誤時拋出
*/
public static String readURLToString(URL source) throws IOException {
return readURLToString(source, null);
}
/**
* 從 URL 讀取內容並轉為字串(指定編碼)
* @param source 目標 URL
* @param encoding 字元編碼(如 "UTF-8", "GB2312"),null 時使用平台預設
* @return URL 回應的字串內容
* @throws IOException 發生 I/O 錯誤時拋出
*/
public static String readURLToString(URL source, String encoding) throws IOException {
InputStream input = source.openStream();
try {
return IOUtils.toString(input, encoding);
} finally {
IOUtils.closeQuietly(input);
}
}
使用範例:
// 簡單 GET 請求
String content = FileUtils.readURLToString(new URL("https://example.com"));
// 指定編碼(適用於繁體中文網頁常用的 Big5 或 UTF-8)
String content = FileUtils.readURLToString(new URL("https://example.com"), "UTF-8");
當需要以 POST 方式請求並傳遞表單參數時,可使用以下方法:
/**
* 以 POST 方式請求 URL 並讀取回應內容
* @param url 目標 URL
* @param encoding 字元編碼
* @param params 請求參數 Map(key=參數名, value=參數值)
* @return 伺服器回應字串
* @throws IOException 發生 I/O 錯誤時拋出
*/
public static String readURLToStringByPOST(URL url, String encoding, Map<String, String> params) throws IOException {
HttpURLConnection con = null;
StringBuilder sb = new StringBuilder();
// 建立查詢字串
if (params != null) {
for (Map.Entry<String, String> entry : params.entrySet()) {
sb.append(entry.getKey()).append('=').append(entry.getValue()).append('&');
}
if (sb.length() > 0) {
sb.setLength(sb.length() - 1); // 移除尾端 '&'
}
}
try {
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setDoInput(true);
con.setUseCaches(false);
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
try (OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream(), encoding)) {
if (params != null) {
osw.write(sb.toString());
}
osw.flush();
}
} catch (Exception e) {
// 建議使用 SLF4J/Log4j2 等現代日誌框架
System.err.println("POST 請求失敗: " + url + ", 錯誤: " + e.getMessage());
} finally {
if (con != null) {
con.disconnect();
}
}
// 讀取回應
StringBuilder buffer = new StringBuilder();
try (BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), encoding))) {
String line;
while ((line = br.readLine()) != null) {
buffer.append(line).append('\n');
}
} catch (Exception e) {
e.printStackTrace();
}
return buffer.toString();
}
POST 使用範例:
Map<String, String> params = new HashMap<>();
params.put("username", "user123");
params.put("action", "login");
String response = FileUtils.readURLToStringByPOST(
new URL("https://api.example.com/login"),
"UTF-8",
params
);
StandardCharsets.UTF_8,避免跨平台亂碼。Result<T> 物件,而非直接列印堆疊追蹤。con.setConnectTimeout() 與 con.setReadTimeout() 防止阻塞。透過簡單封裝 IOUtils 與 HttpURLConnection,即可滿足大多數「從 URL 讀取字串」的需求。若專案已引入 Commons IO,這組工具方法可直接整合至專案共用模組,提升開發效率。