Java 6 引入 java.awt.Desktop API,提供**跨平台**啟動預設瀏覽器、郵件客戶端、編輯檔案、列印等功能。本文詳細說明開啟網頁的完整實作、異常處理、支援度檢查與常見坑。
package com.yifang.demo;
import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class OpenPageDemo {
public static void main(String[] args) {
String url = "https://www.example.com"; // 建議使用 HTTPS
openUrlInDefaultBrowser(url);
}
/**
* 使用系統預設瀏覽器開啟指定 URL
* @param urlString 完整 URL 字串
* @return true 成功啟動,false 失敗或不支援
*/
public static boolean openUrlInDefaultBrowser(String urlString) {
// 1. 基本驗證
if (urlString == null || urlString.trim().isEmpty()) {
System.err.println("URL 不可為空");
return false;
}
// 2. 解析 URI(檢查格式合法性)
URI uri;
try {
uri = new URI(urlString);
} catch (URISyntaxException e) {
System.err.println("URL 格式錯誤: " + urlString);
e.printStackTrace();
return false;
}
// 3. 取得 Desktop 實例
Desktop desktop = Desktop.getDesktop();
// 4. 關鍵:檢查 BROWSE 動作是否支援(某些 Linux 無桌面環境、Headless 模式會失敗)
if (!desktop.isSupported(Desktop.Action.BROWSE)) {
System.err.println("當前環境不支援 Desktop.Action.BROWSE");
return false;
}
// 5. 執行開啟
try {
desktop.browse(uri);
System.out.println("已請求系統開啟瀏覽器: " + uri);
return true;
} catch (IOException e) {
System.err.println("啟動瀏覽器失敗: " + e.getMessage());
e.printStackTrace();
return false;
} catch (NullPointerException e) {
// URI 為 null 時拋出(雖然前面已檢查,但以防萬一)
System.err.println("URI 解析異常");
e.printStackTrace();
return false;
}
}
}
| Action | 功能 | 典型用途 |
|---|---|---|
BROWSE | 開啟 URI(網頁、mailto:、tel: 等) | 開啟官網、聯繫我們郵件連結 |
EDIT | 用預設編輯器開啟檔案 | 開啟 README.txt、設定檔 |
OPEN | 用關聯應用程式開啟檔案 | 開啟 PDF、圖片、Word 文件 |
PRINT | 列印檔案 | 直接列印報表、發票 |
MAIL | 開啟郵件客戶端撰寫郵件 | mailto: 連結 |
| 作業系統 | JRE 版本 | BROWSE 支援 | 備註 |
|---|---|---|---|
| Windows 10/11 | JDK 8+ | ✅ 完美 | 呼叫預設瀏覽器 |
| macOS | JDK 8+ | ✅ 完美 | 呼叫 Safari/Chrome 等預設 |
| Ubuntu (GNOME/KDE) | JDK 8+ | ✅ 通常支援 | 需安裝 libwebkit2gtk 等桌面庫 |
| CentOS (無桌面/Headless) | JDK 8+ | ❌ 不支援 | isSupported 回傳 false,拋 HeadlessException |
| Docker 容器 (無 GUI) | JDK 8+ | ❌ 不支援 | 同上,需安裝 X11/Xvfb 才能測試 |
Exception in thread "main" java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation which requires it.
解決:
-Djava.awt.headless=false(需有圖形介面)GraphicsEnvironment.isHeadless() 為 true 時跳過/改用命令列開啟# Ubuntu/Debian
sudo apt-get install libwebkit2gtk-4.0-37 libgtk-3-0
# CentOS/RHEL
sudo yum install webkitgtk4 gtk3
必須先編碼:
String rawUrl = "https://example.com/search?q=中文 關鍵字";
String encodedUrl = rawUrl; // 若已編碼則跳過
// 若需手動編碼查詢參數:
// String encodedUrl = "https://example.com/search?q=" + URLEncoder.encode("中文 關鍵字", "UTF-8");
openUrlInDefaultBrowser(encodedUrl);
desktop.browse(uri) 是**非阻塞**的:它請求作業系統啟動瀏覽器,隨即返回。Java 程式**無法知道**瀏覽器是否真正開啟、使用者是否關閉視窗。
public static boolean openUrlFallback(String url) {
String os = System.getProperty("os.name").toLowerCase();
try {
if (os.contains("win")) {
Runtime.getRuntime().exec(new String[]{"cmd", "/c", "start", "", url});
} else if (os.contains("mac")) {
Runtime.getRuntime().exec(new String[]{"open", url});
} else if (os.contains("nix") || os.contains("nux")) {
// 嘗試常見 Linux 開啟命令
String[] browsers = {"xdg-open", "gnome-open", "kde-open", "firefox", "chrome", "chromium"};
for (String browser : browsers) {
try {
Process p = Runtime.getRuntime().exec(new String[]{browser, url});
if (p.waitFor() == 0) return true;
} catch (Exception ignored) {}
}
}
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
Desktop.browse() 是 Java 跨平台開啟瀏覽器的**標準首選方案**,代碼簡潔、無第三方依賴。關鍵在於:
isSupported(Action.BROWSE)** 避免 Headless 環境拋異常。IOException 與 URISyntaxException**。