A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 我是楠楠 于 2016-9-1 10:45 编辑

JavaWeb中文编码问题方法解析
--文/郑州中心Java教研部刘老师

因为计算机只识别0与1,在网络上想要传输各种字符就需要进行编码。由于编码、传输、解码过程存在各种不确定性,所以导致乱码问题频发,这成为困扰初学者的一大问题。本文将用最简单的示例解析乱码问题。
一、为什么会出现乱码?
如同发电报一样,如果发报者采用一个密码本进行发报,而接收端采用另外的密码本进行解码,肯定会导致无法解码。如果在计算机网络中传输数据,发送端采用的编码和接收端采用的编码不一致,也会导致乱码问题。常见的编码主要有ASCII、ISO-8859-1、GBK/GB2312、Unicode、UTF-8、UTF-16。
二、乱码处理方式
乱码的处理问题因为产生原因不同,采用的方法也不同,现根据不同的问题分情况讨论:
1.响应中的乱码处理
A. 使用字节输出流输出响应:
String data = "传智播客";
response.getOutputStream().write(data.getBytes());
经实测不会发生乱码问题,原因是String的getBytes()方法默认使用本地平台默认编码将字符串转换为字节数组,中文的Windows操作系统默认使用GBK编码。而在用户端,浏览器默认也使用操作系统默认编码解析网页,在Windows系统下默认也是GBK。发送端及接收端编码一致,所以不会产生乱码问题。
由于UTF-8编码是国际上通用的编码,所以我们在做Web开发时,通常使用UTF-8编码。但是如果使用getBytes("UTF-8")得到字节数组,并发送给客户端,此时会产生乱码问题。原因是getBytes("UTF-8")实际是指定按照UTF-8编码将字符串转换成字节数组,而浏览器此时默认仍然使用本地平台默认编码进行解码就会发生乱码问题。显示效果如下:

此时可以使用以下方式解决乱码问题:
        方法一:手工调整浏览器的编码
点击鼠标右键,在弹出菜单中选择编码,之后选择UTF-8编码。

方法二:使用HTML规范中的META标签设置

添加上述代码后,文字显示正常。
方法三:使用Response对象的setHeader()方法设置Content-Type头
另外,按照HTTP协议的规定,如果指定了消息正文的MIME类型,浏览器必须按照MIME类型解析,所以可以通过设置响应消息头Content-Type的值为text/html,并指定参数charset=UTF-8来使浏览器使用UTF-8解析页面。


方法四:使用Response对象的setContentType()方法设置MIME类型及编码
由于方法三的使用频率比较高,所以在制定Servlet规范时,JCP组织抽取了一个比较简单的方法,此方法与方法三的原理相同,只是更简单,在实际工作中,我们通常使用此方法指定MIME类型。



A.
使用字符输出流输出响应:
Response对象的getWriter()方法可以返回一个PrintWriter对象,输出的内容会暂存在缓冲区中。当响应结束时,Tomcat使用默认编码ISO-8859-1将Response对象的响应消息正文转换为二进制数据输出给客户端,而浏览器使用本地平台默认编码进行解码,从而导致乱码。


处理方式:使用response.setCharacterEncoding("UTF-8")方法告知Tomcat使用UTF-8而不是ISO-8859-1对响应消息正文进行编码。另外,还需要使用response.setContentType("text/html;charset=UTF-8")告知浏览器使用UTF-8编码解码传递过来的数据。

修改后的显示效果如下:

 2.请求中的乱码处理
在用户提交表单时,浏览器会按照当前页面的编码设置对中文字符进行编码,并将内容生成请求消息发送给服务器进行解析。Tomcat服务器得到请求消息后,会依据表单数据的位置不同,做不同的处理。
当提交方法(method)是POST时,表单数据会置于请求消息正文中,Tomcat默认使用ISO-8859-1对此部分内容进行解码,此时需要使用Request.setCharacterEncoding("UTF-8")告知服务器使用UTF-8编码对请求消息正文进行解码。


当提交方法(method)是GET时,表单数据会置于请求消息行中,并使用URL标准编码方式进行二次编码,Tomcat得到此部分数据后,会先使用URL标准规范进行解码,然后默认使用ISO-8859-1进行二次解码。此时如果使用Request.getParamater()方法得到String字符串是经过ISO-8859-1解码的字符串,乱码问题就会发生。对于这种情况,需要将得到的字符串重新按照ISO-8859-1打回字节数组,再次解码。




3.Cookie中的乱码处理
因为Cookie分别使用Set-Cookie和Cookie消息头在响应和请求消息头中进行传输,而HTTP协议中,响应消息和请求消息中只能使用英文字符,中文字符是不安全字符,无法直接使用,故将中文存入Cookie时,需要进行编码操作。我们可以使用URLEncoder工具类的encode()方法对中文进行编码,在读取时使用URLDecoder工具类的decode()方法进行解码。
使用URLEncoder.encode()方法对username字符串进行编码后再创建Cookie对象如图:

使用URLDecoder.decode()方法对username字符串进行解码,如下图:


入学不花一分钱,0基础学编程让你月薪过万
0371-56061160/61/62

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马