java.net.URL 代表統一資源定位符,是 Java 網絡編程的入口類。本文通過實例講解 URL 組件解析、openStream() 讀取遠程資源、openConnection() 進階控制(如下載二進制文件)、編碼處理與常見陷阱。
URL url = new URL("https://www.cnblogs.com/gode/p/5812013.html");
System.out.println("協議: " + url.getProtocol()); // http
System.out.println("主機: " + url.getHost()); // www.cnblogs.com
System.out.println("端口: " + url.getPort()); // -1 (默認端口)
System.out.println("路徑: " + url.getPath()); // /gode/p/5812013.html
System.out.println("文件: " + url.getFile()); // /gode/p/5812013.html
System.out.println("錨點: " + url.getRef()); // null
System.out.println("查詢: " + url.getQuery()); // null
public static String fetchHtml(String urlString) throws IOException {
URL url = new URL(urlString);
try (InputStream is = url.openStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append('\n');
}
return sb.toString();
}
}
輸出為完整 HTML 源碼(含標籤、JS、CSS 引用),而非渲染後的可視文本。
url.openStream() 返回原始字節流,適用於文本;若需處理重定向、設置請求頭、獲取 Content-Type/Content-Length,應使用 URLConnection:
public static void downloadFile(String urlString, String destPath) throws IOException {
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
// 可選:模擬瀏覽器 User-Agent,防 403
conn.setRequestProperty("User-Agent", "Mozilla/5.0");
try (InputStream is = conn.getInputStream();
FileOutputStream fos = new FileOutputStream(destPath)) {
byte[] buffer = new byte[8192];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
System.out.println("下載完成: " + destPath);
}
}
public class UrlDemo {
public static void main(String[] args) {
String blogUrl = "https://www.cnblogs.com/gode/p/5812013.html";
String localFile = "blog_backup.html";
try {
// 方式 1:直接 openStream
// downloadFile(blogUrl, localFile);
// 方式 2:URLConnection 顯式控制
URL url = new URL(blogUrl);
URLConnection conn = url.openConnection();
conn.setRequestProperty("User-Agent", "Mozilla/5.0");
try (InputStream is = conn.getInputStream();
FileOutputStream fos = new FileOutputStream(localFile)) {
byte[] buf = new byte[1024];
int n;
while ((n = is.read(buf)) != -1) {
fos.write(buf, 0, n);
}
}
System.out.println("保存成功,打開 " + localFile + " 即可查看完整頁面結構。");
} catch (IOException e) {
e.printStackTrace();
}
}
}
| 異常 | 原因 | 對策 |
|---|---|---|
MalformedURLException | URL 字符串格式錯誤(如缺協議、非法字符) | 捕獲異常,校驗輸入;使用 URI 類預解析 |
UnknownHostException | DNS 解析失敗 | 檢查網絡/域名;捕獲後重試或降級 |
ConnectException | 連接超時/拒絕 | 設置連接超時 conn.setConnectTimeout(5000) |
SocketTimeoutException | 讀取超時 | 設置讀取超時 conn.setReadTimeout(10000) |
FileNotFoundException (HTTP 404) | 資源不存在 | 檢查 URL;捕獲後記錄日誌 |
new InputStreamReader(is, StandardCharsets.UTF_8) 或根據 conn.getContentEncoding() 動態判斷。setConnectTimeout/setReadTimeout。URL 類提供輕量級網絡資源訪問能力:openStream() 適合簡單文本獲取;openConnection() 解鎖完整 HTTP 控制(請求頭、重定向、響應碼、緩存)。掌握流式讀寫、編碼處理、異常捕獲與超時控制,是 Java 網絡編程的基本功。