encodeURI/decodeURI: 这是 JavaScript 中的函数,它们用于对完整的 URI(统一资源标识符)进行编码和解码,它们会编码空格为%20,但不会编码像~!@#$&*()=:/,;?+'这样的保留字符,因为这些字符在 URI 中有特殊含义。encodeURIComponent/decodeURIComponent: 这也是 JavaScript 中的函数,它们用于对 URI 的某个组成部分(如查询参数、片段)进行编码和解码,它们会编码所有非字母数字字符,包括~!@#$&*()=:/,;?+'等保留字符。
在 Java 中,我们没有直接命名为 encodeURI 的方法,但我们可以使用 java.net 包中的类来实现完全相同的功能。

Java 中的 encodeURI 等价实现
encodeURI 的主要作用是编码一个完整的 URL,确保它是一个合法的字符串,同时保留 URL 结构中的特殊字符(如 , , 等)。
在 Java 中,我们可以使用 java.net.URLEncoder 和 java.net.URLDecoder,但需要注意它们的默认行为。
实现 encodeURI (JavaScript)
Java 中最直接的等价物是 URLEncoder.encode(),但需要指定正确的字符集,并且只对特定部分进行编码。
核心思路:
一个完整的 URI 通常由多个部分组成,scheme://host/path?query#fragment。
encodeURI 会编码除 A-Z a-z 0-9 - _ . ! ~ * ' ( ) ; / ? : @ & = + $ , # 之外的所有字符。

我们可以使用 URLEncoder.encode(),然后手动反转它对 和 等字符的编码,因为 URLEncoder 的编码规则更严格(它基于 application/x-www-form-urlencoded 规范)。
推荐方法:使用 java.net.URI 类
URI 类在构造时会自动处理编码,这是最安全、最符合标准的方式。
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class EncodeUriExample {
public static void main(String[] args) throws URISyntaxException, UnsupportedEncodingException {
String originalUrl = "https://example.com/search?q=java 编程语言 &page=1#section1";
// --- 方法一:使用 java.net.URI (推荐) ---
// URI 类在创建时会自动对路径、查询、片段等部分进行编码。
// 这最接近 encodeURI 的行为。
URI uri = new URI(
"https", // scheme
"example.com", // host
"/search", // path
"q=java 编程语言 &page=1", // query
"section1" // fragment
);
String encodedWithUri = uri.toString();
System.out.println("使用 java.net.URI 编码 (推荐):");
System.out.println(encodedWithUri);
// 输出: https://example.com/search?q=java%20%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80%20&page=1#section1
// 注意:空格被编码为 %20,中文被正确编码。& 在查询字符串中是合法的,所以不会被编码。
System.out.println("\n----------------------------------\n");
// --- 方法二:手动使用 URLEncoder (不推荐,容易出错) ---
// 这种方法比较麻烦,需要先编码,然后再解码一些被过度编码的字符。
String encodedWithUrlEncoder = URLEncoder.encode(originalUrl, StandardCharsets.UTF_8.name());
System.out.println("直接使用 URLEncoder.encode (结果不正确):");
System.out.println(encodedWithUrlEncoder);
// 输出: https%3A%2F%2Fexample.com%2Fsearch%3Fq%3Djava+%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80+%26page%3D1%23section1
// 注意:它把 /, :, ?, # 等所有特殊字符都编码了,这不是 encodeURI 的行为。
// 手动修正(复杂且不推荐)
// String manuallyFixed = encodedWithUrlEncoder.replace("%3A", ":")
// .replace("%2F", "/")
// .replace("%3F", "?")
// .replace("%23", "#")
// .replace("%26", "&");
// System.out.println("手动修正后的结果:");
// System.out.println(manuallyFixed);
}
}
在 Java 中,要实现 JavaScript encodeURI 的功能,最佳实践是使用 java.net.URI 类来构建 URL,而不是直接使用 URLEncoder。
Java 中的 decodeURI (JavaScript) 等价实现
decodeURI 用于解码由 encodeURI 编码的字符串。

在 Java 中,我们可以使用 URLDecoder.decode()。
实现 decodeURI (JavaScript)
URLDecoder.decode() 方法可以直接完成解码工作。
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
public class DecodeUriExample {
public static void main(String[] args) throws UnsupportedEncodingException, URISyntaxException {
// 这是一个由 JavaScript encodeURI 编码后的字符串
String encodedUri = "https://example.com/search?q=java%20%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80%20&page=1#section1";
System.out.println("原始编码后的 URI: " + encodedUri);
// 使用 URLDecoder.decode 进行解码
// 注意:解码整个字符串时,字符集至关重要,通常使用 UTF-8
String decodedUri = URLDecoder.decode(encodedUri, StandardCharsets.UTF_8.name());
System.out.println("\n解码后的 URI: " + decodedUri);
// 输出: https://example.com/search?q=java 编程语言 &page=1#section1
}
}
encodeURIComponent / decodeURIComponent 的 Java 实现
这比 encodeURI 更常用,尤其是在处理查询参数时。
实现 encodeURIComponent (JavaScript)
encodeURIComponent 会编码所有非字母数字字符,非常适合对单个参数值进行编码。
在 Java 中,URLEncoder.encode() 恰好是实现 encodeURIComponent 的完美工具,但需要注意,它会把空格编码为 ,而 JavaScript 编码为 %20,我们可以通过替换来统一。
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class EncodeURIComponentExample {
public static void main(String[] args) throws UnsupportedEncodingException {
String paramValue = "value with spaces & special chars: 中文";
// 使用 URLEncoder.encode 来实现 encodeURIComponent
String encodedValue = URLEncoder.encode(paramValue, StandardCharsets.UTF_8.name());
// URLEncoder 默认将空格编码为 +,而 encodeURIComponent 编码为 %20
// 为了与 JavaScript 行为完全一致,进行替换
String encodedValueLikeJs = encodedValue.replace("+", "%20");
System.out.println("原始参数值: " + paramValue);
System.out.println("使用 URLEncoder 编码 (替换空格后): " + encodedValueLikeJs);
// 输出: value%20with%20spaces%20%26%20special%20chars%3A%20%E4%B8%AD%E6%96%87
}
}
实现 decodeURIComponent (JavaScript)
decodeURIComponent 用于解码由 encodeURIComponent 编码的字符串。
在 Java 中,URLDecoder.decode() 是其等价物,它会自动将 解码为空格。
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
public class DecodeURIComponentExample {
public static void main(String[] args) throws UnsupportedEncodingException {
// 这是一个由 JavaScript encodeURIComponent 编码后的字符串
String encodedParam = "value%20with%20spaces%20%26%20special%20chars%3A%20%E4%B8%AD%E6%96%87";
System.out.println("原始编码后的参数: " + encodedParam);
// 使用 URLDecoder.decode 进行解码
String decodedParam = URLDecoder.decode(encodedParam, StandardCharsets.UTF_8.name());
System.out.println("\n解码后的参数: " + decodedParam);
// 输出: value with spaces & special chars: 中文
}
}
总结与最佳实践
| JavaScript 函数 | Java 等价实现 | 关键点 | 示例 |
|---|---|---|---|
encodeURI(uri) |
new URI(scheme, host, path, query, fragment).toString() |
推荐用于完整 URL,自动处理各部分编码,保留 , , 等结构字符。 | new URI("https", "host", "/path", "q=参数", "frag").toString() |
decodeURI(encodedUri) |
URLDecoder.decode(encodedUri, "UTF-8") |
直接解码整个 URI。 | URLDecoder.decode("...", StandardCharsets.UTF_8.name()) |
encodeURIComponent(value) |
URLEncoder.encode(value, "UTF-8").replace("+", "%20") |
推荐用于单个参数值,编码所有非字母数字字符。 | URLEncoder.encode("...", StandardCharsets.UTF_8.name()) |
decodeURIComponent(encodedValue) |
URLDecoder.decode(encodedValue, "UTF-8") |
直接解码单个参数值。 | URLDecoder.decode("...", StandardCharsets.UTF_8.name()) |
核心要点:
- 字符集是关键:始终指定字符集,最好是
StandardCharsets.UTF_8,如果不指定,会使用平台的默认字符集,这可能导致跨平台问题。 - 区分用途:
- 如果你要处理整个 URL,请优先使用
java.net.URI类。 - 如果你要处理URL 的单个组成部分(如查询参数值),请使用
URLEncoder/URLDecoder。
- 如果你要处理整个 URL,请优先使用
- 空格编码差异:
URLEncoder默认将空格编码为 ,而 JavaScript 的encodeURIComponent编码为%20,在需要完全模拟 JS 行为时,记得进行替换。
