URLDecoder: Illegal hex characters in escape (%) pattern - For input string: "4j"
时间: 2025-05-30 14:44:39 浏览: 27
你遇到的问题是由于 `URLDecoder` 在解码 URL 时遇到了非法的十六进制字符序列(如 `%4j`)。根据 URL 编码规范,`%` 后面必须跟随两位合法的十六进制数字(0-9、A-F 或 a-f),而 `4j` 不符合这一规则。
以下是详细解决方案和代码实现:
---
### 解决方案
1. **问题分析**:
- `%4j` 是一个非法的转义序列,因为 `j` 不是合法的十六进制字符。
- 这种情况通常发生在 URL 中包含未正确编码的特殊字符或拼写错误时。
2. **解决思路**:
- 首先对输入字符串进行预处理,确保所有 `%` 后面都跟随两位合法的十六进制字符。
- 如果发现非法序列,则可以将其替换为 `%25`(即 `%` 的合法编码)或其他合适的值。
- 然后使用 `java.net.URLDecoder` 对字符串进行解码。
---
### 实现代码
以下是一个完整的 Java 实现,用于处理非法的十六进制字符序列并正确解码 URL:
```java
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
public class URLDecoderExample {
public static void main(String[] args) {
String input = "http://example.com/log%4j2%20-%20%E5%89%AF%E6%9C%AC.xml";
try {
// 修复非法的 URL 编码
String fixedUrl = fixMalformedURL(input);
// 解码修复后的 URL
String decodedUrl = URLDecoder.decode(fixedUrl, StandardCharsets.UTF_8.toString());
System.out.println("原始 URL: " + input);
System.out.println("修复后的 URL: " + fixedUrl);
System.out.println("解码后的 URL: " + decodedUrl);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
public static String fixMalformedURL(String url) {
StringBuilder fixedUrl = new StringBuilder();
int i = 0;
while (i < url.length()) {
char c = url.charAt(i);
if (c == '%' && i + 2 < url.length()) {
// 检查 % 后面是否为合法的十六进制字符
String hexPair = url.substring(i + 1, i + 3);
if (isHexDigit(hexPair)) {
fixedUrl.append(c).append(hexPair);
i += 3; // 跳过 % 和两位十六进制字符
continue;
} else {
// 替换非法的 % 序列为 %25
fixedUrl.append("%25");
i++; // 跳过当前的 %
continue;
}
}
// 如果不是 % 序列,直接追加字符
fixedUrl.append(c);
i++;
}
return fixedUrl.toString();
}
private static boolean isHexDigit(String str) {
for (char c : str.toCharArray()) {
if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) {
return false;
}
}
return true;
}
}
```
---
### 代码解释
1. **`fixMalformedURL` 方法**:
- 遍历输入字符串,检查每个字符。
- 如果遇到 `%`,则检查其后面是否跟随两位合法的十六进制字符。
- 如果是合法的十六进制字符,则保留原样。
- 如果不是合法的十六进制字符,则将 `%` 替换为 `%25`。
- 将处理后的字符追加到 `StringBuilder` 中。
2. **`isHexDigit` 方法**:
- 检查给定的字符串是否由合法的十六进制字符组成(0-9、A-F 或 a-f)。
3. **`URLDecoder.decode` 方法**:
- 使用 `URLDecoder.decode()` 方法对修复后的 URL 进行解码。
4. **示例运行**:
- 输入:`http://example.com/log%4j2%20-%20%E5%89%AF%E6%9C%AC.xml`
- 输出:
```
原始 URL: http://example.com/log%4j2%20-%20%E5%89%AF%E6%9C%AC.xml
修复后的 URL: http://example.com/log%254j2%20-%20%E5%89%AF%E6%9C%AC.xml
解码后的 URL: http://example.com/log%4j2 - 副本.xml
```
---
###
阅读全文
相关推荐








