响应编码问题
1.字符编码介绍
计算机中的信息包括数据信息和控制信息,数据信息又可分为数值和非数值信息。非数值信息和控制信息包括了字母、各种控制符号、图形符号等,它们都以二进制编码方式存入计算机并得以处理,这种对字母和符号进行编码的二进制代码称为字符代码(Character Code)。常见的字符编码有ISO-8859-1、gbk、gb2312、utf-8等。
ISO-8859-1编码是单字节编码,向下兼容ASCII,其编码范围是0x00-0xFF,0x00-0x7F之间完全和ASCII一致,0x80-0x9F之间是控制字符,0xA0-0xFF之间是文字符号,它并不支持中文。
GBK是汉字编码标准之一,全称《汉字内码扩展规范》(GBK即“国标”、“扩展”汉语拼音的第一个字母,英文名称:Chinese Internal Code Specification)。
UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,又称万国码。由Ken Thompson于1992年创建。现在已经标准化为RFC3629。UTF-8用1到6个字节编码UNICODE 字符。用在网页上可以同一页面显示中文简体繁体及其它语言(如英文,日文,韩文)。
由于计算机中存储的都是二进制数据,所以任何东西想存储在计算机中,都需要变成二进制的。因此字符
要先转换成二进制的数字才能存放在计算机中。
如果一个字符存放在计算机中是以gbk编码方式编码,而以utf-8编码方式取出来,那么就会出现乱码。这就是乱码的根源:编码方式和解码方式不一样。
2.响应乱码分析
在之前的学习中,我们使用response对象向浏览器端响应信息,响应的都是英文字符。这些英文字符不会在浏览器端出现乱码,但是一旦响应的是中文,就会出现乱码问题。例如:Writer().write(“你好”),浏览器会出现如图1-1所示效果:
图1-1响应乱码
接下来我们来分析响应出现乱码的原因,首先看下面一张图,如图1-2所示:
unicode编码转换二进制图1-2响应乱码分析
图1-2中,服务器向浏览器响应了三次,这三次响应的结果都不相同。我们来一一分析这三种情况,如下:
(1)服务器端直接响应给浏器端
服务器的默认编码是iso-8859-1,当我们向浏览器端响应消息时,如果没有为响应体指定编码方式,那么就会以服务器的默认编码方式进行编码,然后发送给浏览器,而浏览器会以它默认的编码方式进行解码,由于编码方式和解码方式不一致,最终就导致乱码。
(2)服务器先对响应信息进行编码,然后再响应给浏览器端
response.setCharacterEncoding(“utf-8”)方法,是对响应体信息进行编码,编码方式由该方法的参数指定,这里是utf-8。然后再将响应体发送给浏览器,浏览器还是以它默认的编码方式进行解码,如果浏览器的默认编码方式是gbk,那么仍然会出现乱码。只有它们的编码方式一致时才不会出现乱码。
(3)服务器对响应信息进行编码,并且通知浏览器响应信息是以什么方式编码的,然后再发送响应体给浏览器
response.setContentType(“text/html;charset=utf-8”)方法有两个作用,第一:对响应体信息进行编码,作用同response.setCharacterEncoding(“utf-8”)方法一样;第二:通知浏览器响应体的编码方式,这样浏览器就知道该使用相同的编码方式进行解码。有了这个方法,响应的中文信息就不会在浏览器端发生乱码。
response.setHeader(“Content-Type”,String value)方法与response.setContentType(String type)方法的作用是一样的,我们以后最常使用的是后者。清楚了响应出现乱码的原因,有助于我们处理响应乱码。