问题描述
IDEA中,前台文件编码为utf-8,后台编码为gbk,导致前台传参至后台时出现乱码“???”
原因
使用”用户名” 三个字来分析,它的UTF-8 的字节流为:
[e7 94 a8] [e6 88 b7] [e5 90 8d]
按照三个字节一组分组,用户A将其作为整体交给用户B
用户B不知道是什么字符集,当做GBK处理,而GBK是双字节编码,如下按照两两一组进行分组:
[e7 94] [a8 e6] [88 b7] [e5 90] [8d ?]
可以看到最后剩余一个单字节,此时无法编码为GBK,因此它把 0x8d当做一个未知字符,用一个半角Ascii字符的 “?” 代替,变成了:
[e7 94] [a8 e6] [88 b7] [e5 90] 3f
数据就被破坏了。
另外,ISO-8859-1是单字节编码,它的分组方案是:
[e7] [94] [a8] [e6] [88] [b7] [e5] [90] [8d]
因此ISO-8859-1编码可以作为一种中间转存格式。
如:
//将str转为UTF-8字节流
byte[] byteArray1=str1.getBytes("UTF-8");
//用户A->用户B,B不知来源字符集的情况下,将byteArray1当做一个普通的字节流,按照ISO-8859-1解码为一个unicode字符串
String str2=new String(byteArray1,"ISO-8859-1");
//B将ISO-8859-1编码的unicode字符串转回为byte[],传回至A
byte[] byteArray2=str2.getBytes("ISO-8859-1");
//A重新用UTF-8解码,str3与str1内容相同,不会丢失数据
String str3=new String(byteArray2,"UTF-8");
解决方法
对于项目中出现的问题,可以比较直接地进行解决,在Controller接收前台数据的方法中开头添加一行代码:
//前台utf-8转码为gbk
request.setCharacterEncoding("gbk");