在JSP与MySQL结合的开发场景中,乱码问题是非常常见的故障,通常表现为页面提交的中文数据存入数据库后变成问号,或者从数据库读取的中文数据在页面显示乱码,核心原因是整个数据链路的字符编码没有统一设置。

乱码问题的常见成因
数据从JSP页面到MySQL数据库会经过多个环节,每个环节的编码设置如果不一致就会产生乱码:
- JSP页面本身的编码设置错误,导致页面渲染和提交数据的编码不符合预期
- HTTP请求和响应的编码没有指定,服务器默认使用ISO-8859-1编码处理中文数据
- JDBC连接MySQL时没有指定字符编码,连接过程使用默认编码传输数据
- MySQL服务端的字符集设置不统一,数据库、表、字段的编码不一致
JSP层面的编码设置
首先要保证JSP页面本身的编码统一,需要在JSP页面的头部添加编码声明,指定页面使用UTF-8编码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
这个设置的作用有两个,一是指定JSP文件本身的保存编码为UTF-8,二是告诉浏览器响应内容的编码是UTF-8,避免浏览器用错误编码解析页面内容。
如果是POST请求提交的数据,还需要在获取请求参数之前设置请求的编码,避免服务器用默认编码解析请求参数:
<%
// 设置请求编码为UTF-8,必须在获取参数之前调用
request.setCharacterEncoding("UTF-8");
// 设置响应编码为UTF-8
response.setCharacterEncoding("UTF-8");
// 告诉浏览器响应内容的类型和编码
response.setContentType("text/html;charset=UTF-8");
%>
如果是GET请求出现乱码,因为GET请求的参数会拼接在URL中,服务器默认用ISO-8859-1解析,需要手动转码:
<%
String param = request.getParameter("username");
// 将ISO-8859-1编码的字符串转成UTF-8
if(param != null){
param = new String(param.getBytes("ISO-8859-1"), "UTF-8");
}
%>
JDBC连接MySQL的编码设置
JDBC连接MySQL时,需要在连接URL中指定字符编码,否则连接过程会使用MySQL默认的编码传输数据,很容易出现乱码。正确的连接URL格式如下:
// 连接URL中指定useUnicode和characterEncoding参数 String url = "jdbc:mysql://127.0.0.1:3306/test_db?useUnicode=true&characterEncoding=UTF-8"; String username = "root"; String password = "123456"; // 建立连接 Connection conn = DriverManager.getConnection(url, username, password);
这里的两个参数作用分别是:useUnicode=true表示使用Unicode编码集,characterEncoding=UTF-8指定具体的编码为UTF-8,保证JDBC驱动和MySQL之间传输数据使用UTF-8编码。
MySQL服务端的编码设置
MySQL服务端的编码设置是乱码问题的另一个核心点,需要保证数据库、表、字段的编码统一为UTF-8。首先查看当前MySQL的字符集设置:
-- 查看MySQL的字符集相关变量 SHOW VARIABLES LIKE 'character%'; SHOW VARIABLES LIKE 'collation%';
如果查询结果中不是UTF-8相关编码,需要修改MySQL的配置文件,Windows系统是my.ini,Linux系统是my.cnf,在对应配置段添加以下内容:
[client] default-character-set=utf8mb4 [mysql] default-character-set=utf8mb4 [mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_general_ci
修改完成后重启MySQL服务,之后新建的数据库和表会默认使用UTF-8编码。如果是已经存在的数据库和表,需要手动修改编码:
-- 修改数据库编码 ALTER DATABASE test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -- 修改表的编码 ALTER TABLE user_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -- 修改字段的编码 ALTER TABLE user_table MODIFY COLUMN username VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
这里推荐使用utf8mb4而不是utf8,因为MySQL的utf8是阉割版,只支持3字节的字符,无法存储emoji等特殊字符,utf8mb4是完整的UTF-8编码支持。
乱码问题的排查步骤
如果遇到乱码问题,可以按照以下步骤快速排查:
- 先检查JSP页面的编码声明是否正确,是否设置了
request.setCharacterEncoding - 检查JDBC连接URL是否带了
characterEncoding=UTF-8参数 - 检查MySQL的字符集变量,确认服务端编码是否为UTF-8
- 检查对应数据库、表、字段的编码是否统一
- 如果是GET请求乱码,检查是否做了URL参数的转码处理
只要保证整个数据链路的编码都是UTF-8,就可以彻底解决JSP和MySQL的乱码问题。