问题
平时在读取数据库时,总会遇到中文乱码的问题,有时候读出来的中文变成了一串问号,或者是类似/XXXX的形式,还有就是客户端与服务端请求与响应时也会出现中文乱码,这都是字符集不同的问题引起的。解决的办法就是设置包含中文的字符集,例如常见的utf-8、utf8mb4。
字符集
因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。所以就要使用到字符集,讲二进制代码转化为对应的字符。
编码方式
1、ASCII
最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制11111111=十进制255),0 - 255被用来表示大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。但是并没有包含中文,所以如果使用ascii码字符集读取中文就会乱码。
2、Unicode
Unicode码定义了这个世界上几乎所有字符(当然就包括中文了!)的数字表示,它是一种编码规范。而且Unicode还兼容了很多老版本的编码规范,例如ASCII码。
UTF-8编码
utf-8是unicode的一种实现方式,是一种编码方式。
UTF-8使用一到四个字节来编码一个码点。从0到127的这些码点直接映射成1个字节(对于只包含这个范围字符的文本来说,这一点使得UTF-8和ASCII完全相同)。接下来的1,920个码点映射成2个字节,在BMP里所有剩下的码点需要3个字节。Unicode的其他平面里的码点则需要4个字节。UTF-8是基于8位的码元的,因此它并不需要关心字节顺序(因为字节就是8位的呀,其它UTF-16和UTF-32在不同的机器编译环境下需要考虑字节的顺序问题)。
uf8mb4
utf8mb4兼容utf8,且比utf8能表示更多的字符。在创建数据库时,也可以选择它,但是一般用不到。
3、GBK
GBk支持国际标准ISO/IEC10646-1和国家标准GB13000-1的全部中日韩文字。不论中文英文都是2字节。一般在国内,汉字使用的较多。
排序规则
创建数据库时,也会有对应的排序规则选项。常见的: utf_bin和utf_general_ci
utf_bin
bin 是二进制, a 和 A 会别区别对待。
utf8_bin:字符串每个字符串用二进制数据编译存储。 区分大小写,而且可以存二进制的内容
utf_general_ci
utf8_general_ci 不区分大小写,这个你在注册用户名和邮箱的时候就要使用。
utf8_general_cs 区分大小写,如果用户名和邮箱用这个 就会照成不良后果。
实践
1、写入读取数据库数据乱码
设置连接参数:characerEncoding=UTF-8
jdbc:mysql://localhost:3306/db_name?seUnicode=true&characterEncoding=UTF-8
2、JSP页面中文乱码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UF-8"%>
3、post请求的请求参数为中文时乱码
在解析请求参数之前加上
request.setCharacterEncoding("utf-8");
4、get请求的请求参数为中文乱码,表单提交中文乱码
对于 GET请求,语句 request.setCharacterEncoding(“utf-8”); 对避免中文参数乱码起不到任何作用。
使用String转码
new String(name.getBytes("iso-8859-1"),"utf-8")
//其中name为变量名称