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

Java Web 解決 GET/POST 請求中文亂碼完整方案

     編輯:Java 相關知識

Java Servlet 請求參數中文亂碼徹底解決指南

在 Java Web 開發中,中文亂碼是困擾開發者的經典問題。本文系統梳理 POST 與 GET 請求的編碼差異,提供三種實用解決方案,助你徹底告別亂碼困擾。

問題根源分析

HTTP 協議規定 URL 只能包含 ASCII 字元,中文等非 ASCII 字元必須經過編碼傳輸。POST 請求參數在請求體中,可透過設定字元編碼解決;GET 請求參數附在 URL 後,編碼方式由瀏覽器與伺服器協商決定,處理較為複雜。

方案一:POST 請求統一設定編碼

在 Servlet 或 Filter 中於讀取參數前設定:

request.setCharacterEncoding("UTF-8");

注意:必須在呼叫 getParameter() 之前設定,否則無效。建議在 Filter 中統一處理,確保所有 POST 請求生效。

方案二:GET 請求手動解碼(URLDecoder)

針對 GET 請求,可手動解析查詢字串並解碼:

// 獲取原始查詢字串
String queryString = request.getQueryString();

// 使用 URLDecoder 以 UTF-8 解碼
String decodedString = java.net.URLDecoder.decode(queryString, "UTF-8");

// 解析參數
String[] paramPairs = decodedString.split("&");
for (String pair : paramPairs) {
    String[] keyValue = pair.split("=");
    String paramName = keyValue[0];
    String paramValue = keyValue.length > 1 ? keyValue[1] : "";
    // 此處 paramValue 即為正確解碼後的中文值
}

方案三:GET 請求參數重新編碼(ISO-8859-1 轉 UTF-8)

利用 Servlet 容器預設以 ISO-8859-1 解碼 URL 參數的特性,反向轉換:

// 獲取容器解碼後的參數值(實為錯誤解碼)
String rawValue = request.getParameter("name");

// 將錯誤解碼的字串按 ISO-8859-1 還原為位元組陣列
byte[] bytes = rawValue.getBytes("ISO-8859-1");

// 以正確編碼 UTF-8 重新解析位元組
String correctValue = new String(bytes, "UTF-8");

深度解析:為什麼方案三有效?

  1. 瀏覽器發送 GET 請求時,將中文參數以 UTF-8 編碼後放入 URL
  2. Tomcat 等容器預設使用 ISO-8859-1 解碼 URL 參數
  3. 導致中文字元被錯誤解析為亂碼字串
  4. 將亂碼字串按 ISO-8859-1 編碼回位元組,恰好還原為瀏覽器發送的 UTF-8 位元組序列
  5. 再以 UTF-8 正確解碼位元組,得到原始中文

最佳實踐建議

1. 使用 Filter 統一處理(推薦)

@WebFilter("/*")
public class EncodingFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) 
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        
        // 統一設定請求/回應編碼
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        
        // GET 請求特殊處理
        if ("GET".equalsIgnoreCase(request.getMethod())) {
            request = new HttpServletRequestWrapper(request) {
                @Override
                public String getParameter(String name) {
                    String value = super.getParameter(name);
                    if (value == null) return null;
                    try {
                        return new String(value.getBytes("ISO-8859-1"), "UTF-8");
                    } catch (UnsupportedEncodingException e) {
                        return value;
                    }
                }
            };
        }
        chain.doFilter(request, response);
    }
}

2. Tomcat 8+ 容器層級配置

在 server.xml 的 Connector 中設定:

<Connector port="8080" protocol="HTTP/1.1"
           URIEncoding="UTF-8"
           useBodyEncodingForURI="true" />
  • URIEncoding="UTF-8":指定 URL 解碼編碼
  • useBodyEncodingForURI="true":若請求體已設定編碼,則 URL 也使用該編碼

3. Spring MVC 專案配置

在 web.xml 註冊 CharacterEncodingFilter:

<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

常見坑點提醒

  • 雙重編碼:若前端已編碼,後端又手動解碼,會導致雙重編碼錯誤
  • Filter 順序:編碼 Filter 必須在其他讀取參數的 Filter 之前執行
  • 檔案上傳:Multipart 請求需使用 MultipartFilter 或 Spring 的 MultipartResolver 設定編碼
  • 重定向傳參:redirect: 時中文參數需手動 URLEncoder.encode

掌握編碼原理,配合容器配置與 Filter 統一處理,即可從根源解決 Java Web 中文亂碼問題,避免在業務代碼中散落各種解碼邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved