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

Java URL 傳遞中文參數亂碼徹底解決方案:編碼/解碼最佳實踐

     編輯:Java 相關知識

問題背景

在 Java Web 開發中,通过 URL 參數傳遞中文(如 `` 或 `response.sendRedirect("page?msg=中文")`)是極常見的場景。但由於瀏覽器、Web 容器、Java 內部編碼不一致,極易出現亂碼。本文梳理「編碼→傳輸→解碼」全鏈路,給出生產可用的標準化方案。

核心原理:為什麼會亂碼?

  1. 瀏覽器發起請求:URL 中非 ASCII 字符會被瀏覽器按頁面編碼(或 UTF-8)進行 URL Encode(百分號編碼),如 `中文` → `%E4%B8%AD%E6%96%87`。
  2. Tomcat 解析請求行:Tomcat 8+ 默認用 UTF-8** 解碼 URL;Tomcat 7 默認用 **ISO-8859-1**。若兩者不一致,第一層解碼就出錯。
  3. request.getParameter():再次按容器配置的編碼(或默認 ISO-8859-1)將位元組轉為 Java 字符串(UTF-16)。

亂碼本質:編碼與解碼使用的字符集不匹配。

方案一:標準雙向處理(推薦,適用所有版本)

1. 發送端:URLEncoder.encode

String raw = "中文參數";
String encoded = java.net.URLEncoder.encode(raw, StandardCharsets.UTF_8.name());
// 结果:%E4%B8%AD%E6%96%87%E5%8F%83%E6%95%B0
String url = "/target?msg=" + encoded;
  • 必須指定 UTF-8,避免平台默認編碼差異。
  • 不要手動拼接,防止雙重編碼或漏編碼。

2. 接收端:request.getParameter + 手動轉碼(通用)

String encoded = request.getParameter("msg"); // 容器已按 ISO-8859-1 或 UTF-8 解碼一次
if (encoded != null) {
    // 關鍵:將容器解碼後的字符串「還原」為原始位元組,再按 UTF-8 重組
    String decoded = new String(encoded.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
    // decoded 即為 "中文參數"
}

為什麼用 ISO-8859-1? 它是單字節編碼,0x00~0xFF 一一映射,能無損「還原」容器解碼時產生的位元組序列,再按真實編碼(UTF-8)重組字符串。

方案二:Tomcat 8+ 全局配置 UTF-8(一勞永逸)

修改 server.xml 的 ``,添加 URIEncoding="UTF-8":

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443"
           URIEncoding="UTF-8"
           useBodyEncodingForURI="true" />
  • URIEncoding:指定 URL 解碼字符集(含 Query String)。
  • useBodyEncodingForURI:若為 true,優先用請求體編碼(request.setCharacterEncoding)解碼 URL。

效果:配置後,request.getParameter("msg") 直接返回正確中文,**無需手動轉碼**。但需確保前端頁面編碼也是 UTF-8(``)。

方案三:Spring Boot / Spring MVC 統一攔截器

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Bean
    public FilterRegistrationBean<CharacterEncodingFilter> encodingFilter() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        filter.setForceEncoding(true); // 強制 request/response 編碼
        filter.setForceRequestEncoding(true);
        filter.setForceResponseEncoding(true);
        FilterRegistrationBean<CharacterEncodingFilter> bean = new FilterRegistrationBean<>(filter);
        bean.addUrlPatterns("/*");
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return bean;
    }
}

配合 Tomcat URIEncoding="UTF-8",實現全鏈路 UTF-8 無感知。

常見坑與避雷指南

場景錯誤做法正確做法
JS 構建 URL`url + "?name=" + name``url + "?name=" + encodeURIComponent(name)`
Java 後端重定向`redirect:/page?name=" + name``redirect:/page?name=" + URLEncoder.encode(name, "UTF-8")`
表單 GET 提交依賴瀏覽器默認編碼頁面強制 `` + 後端配置 URIEncoding
雙重編碼前端 encode + 後端再 encode全鏈路只編碼一次,解碼一次

總結

  • 最穩健:前端 `encodeURIComponent` + 後端 Tomcat `URIEncoding="UTF-8"` + 頁面 `charset=UTF-8`,零代碼侵入。
  • 無法改容器配置:後端統一用 new String(param.getBytes(ISO_8859_1), UTF_8) 手動轉碼,或封裝工具類/攔截器。
  • 核心鐵律:編碼解碼字符集**必須完全一致**,全鏈路統一 UTF-8。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved