1、如下设置响应数据时,浏览器默认解码数据使用gbk,项目中getBytes也是默认使用gbk进行编码,因此浏览器显示正确,但是F12查看具体的响应是乱码
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
ServletOutputStream outputStream = response.getOutputStream();
String dataString="测试";
outputStream.write(dataString.getBytes(""));
}
2、如下设置相应数据时,浏览器解码数据使用utf-8,项目中getBytes也是使用utf-8进行编码,因此浏览器显示正确,F12查看具体的响应也是正确的
response.setContentType("text/html;charset=utf-8");
ServletOutputStream outputStream = response.getOutputStream();
String dataString="测试";
outputStream.write(dataString.getBytes("utf-8"));
3、因此产生了疑问,数据编码成字节的格式与浏览器解码字节的格式都一致的情况下,为什么用gbk响应这里是乱码,而用utf-8响应这里是正确的?
4、看了一些视频教程,有解释为http传输数据时始终使用的是ISO8859-1对数据进行了二次解码。但是也没有解决我上述的疑问,根据视频教程的解答,当程序中用utf-8编码成字节写入流中,http传输时使用ISO8859-1可以正确编码成字符,因此F12查看的时候是正确的字符;当使用gbk编码成字节写入流中时,http传输使用ISO8859-1不能正确编码成字符,所以F12查看是乱码
希望各位有经验的朋友帮忙回答下,谢谢
http传输数据时始终使用的是ISO8859-1对数据进行了二次解码这--个不敢苟同
你需要了解下tomcat响应的流程:
response.setContentType("text/html;charset=utf-8");//#1
这行代码有两个含义1.响应给浏览器的时候添加一个content-type的头,让浏览器知道字节数据的转码类型
2.当你通过response。getWriter()。pintln(“xxx”).写入字符串的时候,tomcat会根据你设置的contenttype(utf-8)将字符转换成字节传送到浏览器,
如果你是通过response.getOutputStream()。wite(byte[] data),tomcat不做任何处理直接通过socket输出到浏览器。
正因为有了代码#1所以response。getWriter()。pintln(dataString)和 outputStream.write(dataString.getBytes("utf-8"));是等价的。
再看看下面这段代码:
ServletOutputStream outputStream = response.getOutputStream();
String dataString="测试";
outputStream.write(dataString.getBytes("")); //dataString.getBytes("")以系统默认编码gbk进行字节转换
由于没有调用response.setContentType设置编码类型,此时response。getWriter()。pintln(“xxx”)将会以tomcat默认的iso8859-1,将字符串转成二进制发送出去。但由于你通过 outputStream.write(dataString.getBytes(""));写的是字节,所以tomcat不会做任何特殊处理,直接输出。但由于你没有设编码类型,于是tomcat在响应中不包含头信息,此时浏览器就无法判断字节的实际编码,只能用系统默认编码gbk去解。
而f12工具乱码和浏览器显示不是一回事,工具只是一个插件不代表浏览器行为。工具可能会去找响应的头,如果没有头会用一个默认的编码去解可能是utf8或其他,又或者总是使用utf8,要知道原因,也将你的代码示例1加个gbk的响应类型response.setContentType(“charset=gbk”)看看工具是否还是乱码
如果是java web 工程,将web服务器的配置文件中的响应强词编码改成UTF-8,就可以让服务端 中文不乱码,比如tomcat 下修改server.xml 中
在标签Connector 中加入URIEnCoding="UTF-8"
若不使用setContentType()或setCharacterEncoding()进行设置,服务器将用UTF-8的编码方式向客户端发送数据,而浏览器将用GBK编码显示接收到的数据,这就会导致乱码。但是你的页面上头上也可以设置编码格式
servlet的缓冲区编码是iso-8859-1的编码集,所以你用utf-8转一次是解决不了的,你得先用iso-8859-1的编码解码一次,再用utf-8编码,
ISO8859-1不支持gbk,所以看到是乱码,不管传输采用什么编码,估计都是不支持gbk的,因此设置编码gbk,查看都是乱码