| 編碼 | 類型 | 覆蓋範圍 | 特點 |
|---|---|---|---|
| ISO-8859-1 | 單字節 | 0-255 | 西歐語系,Java 默認網絡傳輸編碼 |
| GB2312/GBK | 雙字節 | 簡體/簡繁中文 | 中文 Windows 默認,兼容 ASCII |
| UTF-16 (Unicode) | 定長雙字節 | 全字符集 | Java 內存/字符串內部編碼 |
| UTF-8 | 變長 1-4 字節 | 全字符集 | 兼容 ASCII,網絡傳輸/存儲首選 |
// String → byte[] (編碼)
byte[] utf8 = "中文".getBytes(StandardCharsets.UTF_8); // [0xE4,0xB8,0xAD,0xE6,0x96,0x87]
byte[] gbk = "中文".getBytes("GBK"); // [0xD6,0xD0,0xCE,0xC4]
// byte[] → String (解碼)
String s1 = new String(utf8, StandardCharsets.UTF_8); // "中文"
String s2 = new String(gbk, "GBK"); // "中文"
// 關鍵:編解碼必須成對,否則亂碼
// 可逆性:new String(str.getBytes("UTF-8"), "UTF-8") == str
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>request.setCharacterEncoding("UTF-8")(必須在首次 getParameter() 前調用,僅對 POST 有效)response.setCharacterEncoding("UTF-8") + response.setContentType("text/html;charset=UTF-8")SetCharacterEncodingFilter (Spring 内置)-- MySQL 建庫建表
CREATE DATABASE app DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE TABLE t (c VARCHAR(100)) CHARSET=utf8mb4;
-- JDBC 連接串
jdbc:mysql://host:3306/app?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull
utf8mb4 支持 Emoji(4 字節),utf8 僅 3 字節。
IE「總是使用 UTF-8 發送 URL」選項導致同一鏈接到達服務器編碼不同:
public static String decodeUrlParam(String raw, String defaultCharset) {
try {
byte[] bytes = raw.getBytes("ISO-8859-1"); // 還原 Servlet 容器按 ISO-8859-1 解碼後的字節
if (isValidUtf8(bytes)) {
return new String(bytes, "UTF-8");
}
return new String(bytes, defaultCharset); // 如 GBK
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException(e);
}
}
private static boolean isValidUtf8(byte[] bytes) {
int i = 0;
while (i < bytes.length) {
int b = bytes[i++] & 0xFF;
if (b < 0x80) continue; // ASCII
int expected;
if ((b & 0xE0) == 0xC0) expected = 1;
else if ((b & 0xF0) == 0xE0) expected = 2;
else if ((b & 0xF8) == 0xF0) expected = 3;
else return false;
if (i + expected > bytes.length) return false;
for (int j = 0; j < expected; j++) {
if ((bytes[i++] & 0xC0) != 0x80) return false;
}
}
return true;
}
注意:極少數 GBK 字節序列誤判為合法 UTF-8(如「學習」),可結合 `Accept-Language` 頭輔助判斷。