**亂碼 = 編碼與解碼使用了不同的字符集**
字符串在記憶體中為 Unicode (UTF-16),進行 I/O 時必須明確指定編碼:
| 場景 | 錯誤用法 | 正確用法 | 原因 |
|---|---|---|---|
| 構造 String | `new String(bytes)` | `new String(bytes, StandardCharsets.UTF_8)` | 預設使用平台編碼 (Windows=GBK, Linux=UTF-8) |
| 獲取字節 | `str.getBytes()` | `str.getBytes(StandardCharsets.UTF_8)` | 同上,跨平台不一致 |
| 文件讀寫 | `new FileReader(file)` | `new InputStreamReader(new FileInputStream(file), "UTF-8")` | FileReader 無法指定編碼 |
| 網絡傳輸 | `PrintStream` 無編碼 | `new PrintStream(out, true, "UTF-8")` | PrintStream 預設平台編碼 |
| 控制台輸出 | `System.out.println()` | IDE/終端設置 UTF-8,JVM 參數 `-Dfile.encoding=UTF-8` | 控制台編碼可能非 UTF-8 |
<%@ page pageEncoding="UTF-8" contentType="text/html;charset=UTF-8" %> <meta charset="UTF-8" />
@WebFilter("/*")
public class EncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
chain.doFilter(req, resp);
}
}
<Connector port="8080" URIEncoding="UTF-8" /> <!-- POST 請求體編碼需 Filter 支持,GET 參數由 URIEncoding 決定 -->
jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
頁面 `