首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java URL 建構常見陷阱與正確解決方案:從 URLEncoder 到 UrlBuilder

     編輯:Java 相關知識

核心誤區:URLEncoder 不是 URL 編碼器

java.net.URLEncoder 類名極具誤導性,其 Javadoc 首句即說明:Utility class for HTML form encoding。它實現的是 application/x-www-form-urlencoded(表單編碼),而非 RFC 3986 定義的 URL 百分號編碼。

陷阱實例

場景 1:查詢參數值包含特殊字符

// 正確:查詢參數值用 URLEncoder
String q = URLEncoder.encode("You & I", "UTF-8"); // "You+%26+I"
String url = "https://foo.com/search?q=" + q;    // 可行

空格變 +,& 變 %26,符合表單編碼規則。

場景 2:路徑段落包含特殊字符

// 錯誤:路徑段落用 URLEncoder
String path = URLEncoder.encode("You & I", "UTF-8"); // "You+%26+I"
String url = "https://foo.com/search/" + path;      // 解碼後變 "/search/You+&+I" 錯誤!

路徑中 + 不會被解碼為空格,導致語義錯誤。

更深層陷阱:URI / HttpBuilder 的雙重編碼

java.net.URI 多參數建構子假設路徑「已正確編碼 /,其餘未編碼」,導致 /foo%2Fbar 被再次編碼為 /foo%252Fbar。Groovy HttpBuilder 內部依賴 URI,同樣受影響。

正確解決方案:分層編碼策略

URL 各組件編碼規則不同,必須分別處理:

推薦庫:UrlBuilder(或 OkHttp HttpUrl、Spring UriComponentsBuilder)

// UrlBuilder 風格流式 API
String url = UrlBuilder.forHost("http", "foo.com")
    .pathSegment("with spaces")           // 自動編碼空格 → %20
    .pathSegments("path", "with", "varArgs")
    .pathSegment("&=?)")                  // 路徑中 & = ? 需編碼
    .queryParam("fancy + name", "fancy?=value") // 參數值編碼
    .matrixParam("matrix", "param?")      // 矩陣參數
    .fragment("#?=")
    .toUrlString();
// 結果:https://foo.com/with%20spaces/path/with/varArgs/&%3D%3F%29;matrix=param%3F?fancy%20%2B%20name=fancy%3F%3Dvalue#%23%3F%3D

避坑清單

  1. 永不直接用 URLEncoder 拼接完整 URL。
  2. 路徑段落、查詢參數、Fragment 分別編碼。
  3. 使用成熟構建器(UriComponentsBuilder、OkHttp HttpUrl),避免手工拼接錯誤。
  4. 解析 URL 時用 URI 或 HttpUrl.parse,而非正則/字符串分割。

總結

URL 編碼看似簡單,實則暗藏 RFC 3986、RFC 1738、HTML 表單編碼多套規則交織。理解「組件級編碼」原則,配合標準庫構建器,才能構建健壯、安全的網絡請求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
組件允許未編碼字符需編碼字符示例
Scheme字母數字 + - .—
Host域名規則—
Port數字—
Path Segment字母數字 - . _ ~ @ :/ ? # [ ] 空格 & =
Query Param Name/Value字母數字 - . _ ~空格 & = + # ? /
Fragment查詢規則類似—