环境介绍:
Ubuntu 18.04(x86_64)
MySQL v_8.0.22
问题背景:
- 前端提交form表单到Server A
- Server A 转发请求到Server B
- Server B 插入数据到MySQL数据表
表象:
数据表中的中文字段显示为乱码 {???}
解决流程:
问题定位:
- 检查MySQL数据库的编码设置(由于手动插入中文数据没有出现乱码问题,所以这一步骤对我来讲不是那么care)
// 登录mysql
mysql -u root -p
// 检查编码设置
show variables like ‘character%’;
// 结果如下:(正常)
ps:如果编码设置不对可以通过如下修改方案:
- sudo vim /etc/mysql/conf.d/mysql.cnf
// 在[mysql]下面一行 添加如下内容
default-character-set=utf8- sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
// 在[mysql]下 添加如下内容
character-set-server=utf8- service mysql restart
- 最后在登录到mysql使用
show variables like 'character%';
查看编码设置
- 检查目标数据库数据表及表字段的编码设置
// 登录mysql之后
show create table 数据库.数据表;
// 结果我就不截图了,大家可以自己分析自己的数据表及表字段是否为utf8。
=================___
ps: 如果表或者表字段的编码不符合要求。可以使用如下sql修改:
// 登录到mysql后[标红部分填自己的]
ALERT TABLE表名
MODIFY表字段 VARCHAR(32)
CHARACTER SET ‘utf8’;
=================___
当然,如果你们有Navicat之类的可视化工具,也可以直接看编码设置是否符合要求:
数据库连接,右键表 -->设计表 --> 选择目标字段即可查看编码设置:
- 检查Server B数据库连接配置 [没有问题]
spring.datasource.url=jdbc:mysql://localhost:3306/***数据库名***?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimeZone=Asia/Shanghai
- 断点查看各个流程数据的传递情况
- 前端提交form表单到Server A :表单提交的数据格式正常;Server A接收到的数据正常
- Server A 转发请求到Server B :Server A 发送的请求体charset=ISO-8859-1 ,Server B 接收到的数据乱码
- Server B 插入数据到MySQL数据表 :插入的数据为乱码
解决方案:
方案1:
Server A 发送请求时将请求体编码格式指定为
utf-8
。------------------>>> 有坑
/**
* ps:方案1的坑。
* 请求中使用的请求体是org.apache.http.entity.StringEntity(),
* 关于这个类,有如下的方案设置其编码格式。
*/
// 方式 1
StringEnrity stringEntity = new StringEntiry(JSONObject.toJSONString(params));
stringEntity.setContentType("text/plain");
stringEntity.setContentEncoding("UTF-8");
// 方式 2
StringEntity stringEntity = new StringEntity(JSONObject.toJSONString(params), "UTF-8");
上面这两种方式,方式2才能成功解决编码问题。方式1不起作用。原因如下:
// ContentType代码:
ContentType.DEFAULT_TEXT = TEXT_PLAIN = create("text/plain", Consts.ISO_8859_1);
// StringEntity 的源码:
public StringEntity(String string) throws UnsupportEncodingException {
this(string, ContentType.DEFAULT_TEXT);
}
public StringEntity(String string, String charset) {
this(string, ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), charset));
}
能看出来,使用第一种方案
方案2:
Server B 接受到请求之后将编码格式转化为
utf-8
,之后再插入数据库
String param = request.getParameter(“****”);
byte[] paramByteArr = param.getBytes(“iso-8859-1”);
param = new String(paramByteArr, “utf-8”);
祝工作愉快^o^