使用 response.sendRedirect(url) 重導向時,URL 參數包含 JSON 字串(含中文、特殊符號),接收端 request.getParameter("jsonarray2") 拋出 java.io.CharConversionException: isHexDigit。同樣參數用 JavaScript window.location.href 則正常。
URL 參數未經 URL 編碼直接拼接。JSON 字串包含 %、+、=、&、中文等字元,直接放入 Query String 會破壞 URL 結構,Tomcat 解碼時遇到非法十六進位序列(如 %E4 後非十六進位字元)而拋出 CharConversionException。瀏覽器端 JS 自動編碼,故正常。
String json = "{\"1\":\"主營業務成本-網絡運行成本\"}";
String url = "/UEAnalyze/BaoZhang.do?bzApply&jsonarray=" + json; // 直接拼接,未編碼
response.sendRedirect(url);
String json = "{\"1\":\"主營業務成本-網絡運行成本\"}";
String encoded = URLEncoder.encode(json, StandardCharsets.UTF_8.name());
// 關鍵:空格編為 %20 而非 +,RFC 3986 建議
String url = "/UEAnalyze/BaoZhang.do?bzApply&jsonarray=" + encoded;
response.sendRedirect(url);
String encoded = request.getParameter("jsonarray"); // Tomcat 自動解碼 Query String
// 通常無需手動解碼,Tomcat 8+ 預設 UTF-8 解碼
// 若發現亂碼,檢查 server.xml
String json = encoded; // 直接使用
// 或顯式解碼(罕見需要)
// String json = URLDecoder.decode(encoded, StandardCharsets.UTF_8.name());
| 方式 | 編碼行為 |
|---|---|
window.location.href = url | 瀏覽器自動對整個 URL 或參數值執行 encodeURIComponent |
response.sendRedirect(url) | 伺服器端不會自動編碼,開發者必須手動編碼參數值 |
public final class UrlUtil {
private UrlUtil() {}
public static String buildUrl(String base, Map params) {
StringBuilder sb = new StringBuilder(base).append('?');
params.forEach((k, v) -> {
if (sb.length() > base.length() + 1) sb.append('&');
sb.append(encode(k)).append('=').append(encode(v));
});
return sb.toString();
}
public static String encode(String s) {
try {
return URLEncoder.encode(s, StandardCharsets.UTF_8.name())
.replace("+", "%20") // RFC 3986
.replace("*", "%2A")
.replace("~", "%7E");
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("UTF-8 not supported", e);
}
}
}
// 使用
String url = UrlUtil.buildUrl("/UEAnalyze/BaoZhang.do", Map.of(
"bzApply", "",
"jsonarray", json1,
"jsonarray2", json2
));
response.sendRedirect(url);
URL 長度限制(約 2KB~8KB 視瀏覽器/伺服器),JSON 較大時應改為:
Content-Type: application/x-www-form-urlencoded,Body 放編碼後 JSONContent-Type: application/json,Body 直接放原始 JSON,request.getInputStream() 讀取CharConversionException: isHexDigit 經典原因是 URL 參數未編碼。Server-side redirect 必須手動 URLEncoder.encode(..., UTF-8) 每個參數值;接收端通常依賴 Tomcat 自動解碼(確保 URIEncoding="UTF-8")。大量資料請改用 POST Body 傳輸。