Java 內部使用 UTF-16,外部交互(HTTP、JDBC、文件、控制台)涉及多種編碼。亂碼本質是解碼編碼不匹配:按 ISO-8859-1 讀取了 GBK 字節,或反之。
在頁面指令顯式聲明響應編碼:
<%@ page language="java" contentType="text/html; charset=GB2312" pageEncoding="GB2312" %>
或在 Servlet 中:
response.setContentType("text/html;charset=GB2312");
response.setCharacterEncoding("GB2312");
request.setCharacterEncoding("GB2312"); // 必須在 getParameter 前調用
String name = request.getParameter("name");
// 方案一:手動轉碼
String raw = request.getParameter("name");
String name = new String(raw.getBytes("ISO-8859-1"), "GB2312");
// 方案二:配置 server.xml URIEncoding="UTF-8" 統一按 UTF-8 解碼(推薦)
jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=GB2312&zeroDateTimeBehavior=convertToNull
驅動通常自動處理,若出現亂碼嘗試在連接屬性設定 charSet 或 sendStringParametersAsUnicode。
// 讀取 GBK 文件
try (BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream("data.txt"), "GBK"))) { ... }
// 寫入 UTF-8 文件
try (BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream("out.txt"), "UTF-8"))) { ... }
public final class CharsetUtil {
public static String convert(String str, String fromCharset, String toCharset) {
try {
return new String(str.getBytes(fromCharset), toCharset);
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("不支持的編碼", e);
}
}
// 常用組合
public static String isoToGbk(String s) { return convert(s, "ISO-8859-1", "GBK"); }
public static String gbkToIso(String s) { return convert(s, "GBK", "ISO-8859-1"); }
}
getBytes()、new String(bytes)、InputStreamReader 必須顯式指定 charset。