Java的各种中⽂乱码解决⽅法
⼀、Servlet输出乱码
1. ⽤OutStream字节流输出中⽂,假设要输出的是String str ="钓鱼岛是中国的,⽆耻才是⽇本的"。
1.1 若是本地服务器与本地客户端这种就不⽤说了,直接可以out.Bytes())可以输出没有问题。因为服务器中⽤Bytes()是采⽤默认本地的编码,⽐如GBK。⽽浏览器也解析时也⽤本地默认编码,两者是统⼀的,所以没有问题。
1.1 若服务器输出时⽤了, out.Bytes("utf-8"))。⽽本地默认编码是GBK时(⽐例在中国),那么⽤浏览器打开时就会乱码。因为服务器发送过来的是utf-8的1010数据,⽽客户端浏览器⽤了gbk来解码,两者编码不统⼀,肯定是乱码。当然,你也可以⾃⼰将客户端浏览器的编码⼿⼯调⽤下(IE菜单是:查询View->编码encoding->utf-8),但是这种操作很烂,最好由服务器输出响应头告诉,浏览器⽤哪种编码来解码。所以要在服务器的servlet中,增加response.setHeader("content-type","text/html;charset=utf-8"),当然也可直接⽤简单的response.setContentType("text/hmtl;charset=utf-8")。两种的操作是⼀样⼀样的。
2. ⽤Wirter字符流输出中⽂,假设要输出的是String str ="钓鱼岛是中国的,⽆耻才是⽇本的"。
2.1 若写成out.print(str)输出时,客户端浏览器显⽰的将全是多个的字符,代表在编码表中肯定就不到相应的字符来显⽰。原因是:Writer()得到的字符输出流,默认对字符的输出是采⽤ISO-8859-1,⽽ISO-8859-1肯定是不⽀持中⽂的。所以肯定要⾸先要做的第⼀件事:是要将服务器对象输出字符能⽀持中⽂的。其次服务器向客户端写回的响应头要告诉客户端是⽤了哪种编码表进⾏编码的。⽽实现这两个需求,只需要response.setContentType("text/hmtl;charset=utf-8")。就搞定了。特别注意:
response.setContentType("text/html;charset=utf-8")要放在PrintOut out = Writer()代码的前⾯,否则只是有告诉客户端⽤什么码表编码的功能,⽽服务器端还是⽤ISO-8859-1编码了。再特别提⽰下:在同⼀Servlet中的doGet或doPost⽅法中,不能既⽤
⼆、Servlet⽂件下载,中⽂乱码情况。
关键是下载时响应头 content-disposition中attachment;filename=⽂件名。这个⽂件名filename不能是含有中⽂字符串的,要⽤URLEncoding 编码进⾏编码,才能进⾏进⾏http的传输。如下代码⽰例:
三、Servlet的response增加addCookie,cookie中value的中⽂码问题解决⽅法。
关于cookie的原理,见。若想将cookie中存放中⽂的值,必须⽤Base64编码后,发给客户浏览器端进⼊存储。⽽下次客户端浏览访问是带回来的cookie中的值,是经过Base64编码的,所以需要⽤Base64解码即可。 Base64编码主要是解决将特殊字符进⾏重新编码,编码成a-b、A-B、0-9、+与/,字符52,10个数字与⼀个+,⼀个/ 共64个字符。它的原理是将原来3个字节的内容编码成4个字节。主要是取字节的6位后,在前⾯补00组成⼀个新的字节。所以这样原来的3个字节共24,被编码成4个字节32位了。
具体代码⽰例如下:
四、获取请求参数乱码
乱码符号有哪些GET⽅式的乱码:
如<a href=”/demo5/servlet/RD2?name=中国”>CN</a>,直接⽤Parameter得到的字符串strCN将会乱码,这也是因为GET⽅式是⽤http的url传过来的默认⽤iso-8859-1编码的,所以⾸先得到的strCn要再⽤iso-8859-1编码得到原⽂后,再进⾏⽤utf-8(看具体页⾯的charset 是什么utf-8或gbk)进⾏解码即可。new Bytes(“ISO-8859-1”),“UTF-8”);
这种⽅式操作⽐较⿇烦的是,有⼀个参数要⽤iso-8859-1编码⼀次再解码⼀次。
POST⽅式的乱码:只需要request.setCharacterEncoding("UTF-8"):即可。