原則:全鏈路統一 UTF-8(或 GBK),任何一環不一致即亂碼。
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
init_connect='SET NAMES utf8'
重啟 MySQL 生效。
CREATE TABLE `Company` (
`Cname` VARCHAR(10) NOT NULL,
`Caddr` VARCHAR(100),
`Ctel` VARCHAR(16)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
String url = "jdbc:mysql://localhost:3306/test?"
+ "user=root&password=1"
+ "&useUnicode=true"
+ "&characterEncoding=utf-8"
+ "&autoReconnect=true"
+ "&serverTimezone=Asia/Shanghai";
Connection conn = DriverManager.getConnection(url);
useUnicode=true:啟用 Unicode 支持characterEncoding=utf-8:指定傳輸編碼// 讀取請求參數
String name = request.getParameter("name");
name = new String(name.getBytes("ISO-8859-1"), "UTF-8");
// 讀取 ResultSet
String dbValue = new String(rs.getString("col").getBytes("ISO-8859-1"), "UTF-8");
原理:JDBC 驅動默認按 ISO-8859-1 解碼字節,再按目標編碼重組。僅在方案二無效時使用,治標不治本。
<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>
Spring Boot 只需配置:server.servlet.encoding.charset=UTF-8、server.servlet.encoding.force=true。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
CHARSET=utf8(SHOW CREATE TABLE)。useUnicode=true&characterEncoding=utf-8。server.xml <Connector URIEncoding="UTF-8" />。CharacterEncodingFilter 且映射 /*。pageEncoding="UTF-8"。Content-Type: text/html;charset=UTF-8。SET NAMES utf8 執行一次永久生效 → 僅對當前連接有效,需寫入 JDBC URL 或 init_connect。utf8mb4 才是真正 UTF-8,utf8 為 utf8mb3 別名,無法存 Emoji。建議全鏈路升級 utf8mb4。CharacterEncodingFilter 必須在其他讀取請求體的 Filter 之前。