javaWeb -- web中的乱码问题集
笔记摘要:
本文总结了最近web学习中遇到的一些中文乱码问题,其实问题的关键就是,文件保存时的编码,以及服务端对提交的数据进行的编码,和浏览器的编码,只要这三个编码问题搞清楚,就能够彻底解决中文乱码问题,当然以后还会遇到其它类型的乱码问题,相信万变不离其宗。
一、HttpServletResponse向客户端输出中文数据的乱码问题
response向客户端输出数据有两种方式:getOutputStream和getWriter
方式一:使用getOutputStream()
实验:getOutputStream().write("中国".getBytes("utf-8"));出现乱码
原因: getBytes()默认为GB2312,这里指定utf-8,而浏览器是以默认的GB2312打开,所以会出现乱码问题
解决方法:
必须指定浏览器以什么码表解码
1. response.setHeader("content-type", "text/html;charset=utf-8"); //设置请求消息头为utf-8,让浏览器以utf-编码打开
2. <meta http-equiv="" content="">来模拟响应头信息
方式二:getWriter(),获得一个字符输出流
实验:response.getWriter().write("中国");出现乱码
原因:
因为这里获取到的是字符流,所以服务器在返回给浏览器的时候会转换成字节数据,需要进行编码,这时查的是ISO8859-1码表,ISO8859-1码表
中没有中文,所以查到的是"??",而服务器是以GB2312打开,GB2312是兼容ISO8859-1的,所以浏览器直接就输出"??"
解决方案:
方式一
response.setHeader("Content-type", "text/html;charset=utf-8");//设置请求消息头为utf-8,让浏览器以utf-编码打开
response.setCharacterEncoding("utf-8");//设置服务器解析时的编码格式为utf-8
方案二
response.setContentType("text/html;charset=utf-8"); 等价于上面两句
建议:
在使用response.setContentType("text/html;charset=utf-8");的时候加上
response.setCharacterEncoding("utf-8");这样更易于阅读
二、HttpServletRequest请求乱码
提交请求的方式
超链接,表单,直接在服务栏中请求
POST表单
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>3.html</title> </head> <body> <a href="/day05/servlet/ConfusingCodeDemo?user=zhangsan&psw=12345">使用超链接提交数据</a> <hr>
GET表单
<form action="/day05/servlet/ConfusingCodeDemo"> 用户名<input type="text" name="user"> 密码<input type="password" name="psw"> <input type="submit" value="提交"> </form> POST <hr> <form action="/day05/servlet/ConfusingCodeDemo" method="POST"> 用户名<input type="text" name="user"> 密码<input type="password" name="psw"> <input type="submit" value="提交"> </form> </body> </html>
问题原因:
在提交数据的时候,如果是中文(一般默认为GBK),在提交给服务端,在request处理的时候会进行ISO8859-1编码,而ISO8859-1编码不支持GBK,所以会解析成一些乱码,返回给浏览器
POST方式提交解决方法
request.setCharacterEncoding("GB2312");//放在request.getParameter()前面才有效
但是这种方式只对POST提交有用
GET方式提交解决方法(通用,也可以用于POST方式)
先进行ISO8859-1编码,以便服务器端可以识别,然后再使用ISO8859-1编码的字节进行GB2312解码,显示中文
String user = request.getParameter("user");
user = new String(user.getBytes("ISO8859-1"),"GB2312");//先进行ISO8859-1编码,这样服务器端可以识别,然后再使用GBK编码,提交给浏览器
可同时解决POST和GET(不推荐)
修改tomcat的配置文件:http://localhost:8080/docs/config/http.html
URIEncoding 指定服务端的编码
useBodyEncodingForURI :设为true,则POST的提交方式:request.setCharacterEncoding("GB2312");对GET方式也有用
三、实现文件下载时的中文问题
利用response将HTTP的响应头"content-disposition"设置为"attachment;filename=xxx"即可实现文件下载功能
注意:
如果文件名中包含中文,则文件名要进行URL编码:URLEncoding.encode('卡拉.jpg','utf-8');如果不进行编码则文件名显示错误并且不可下载。
private void download(){ String urlName = URLEncoder.encode("考拉.jpg","utf-8");//当响应给浏览器的文件名为中文时,需要进行URL编码,否则出现乱码 response.setHeader("content-disposition","attachment;filename="+urlName); // response.setHeader("content-disposition","attachment;filename=Koala.jpg");//响应给浏览器时文件名是英文时,可以直接下载 InputStream in = this.getServletContext().getResourceAsStream("/Koala.jpg");//获取本地文件并封装成流 OutputStream out = response.getOutputStream(); //文件复制 int len = 0; byte[] buf = new byte[1024]; while((len=in.read(buf))!=-1){ out.write(buf,0,len); } in.close(); }
四、JSP中的乱码问题
使用page指令解决JSP中文乱码
1、JSP程序存在有与Servlet程序完全相同的中文乱码问题
a) 输出响应正文时出现的中文乱码问题
b) 读取浏览器传递的参数信息时出现的中文乱码问题
2、JSP引擎将JSP页面翻译成Servlet源文件时也可能导致中文乱码问题 (文件编码与解析时的编码不同)
a) JSP引擎将JSP源文件翻译成的Servlet源文件默认采用UTF-8编码,而JSP开发人员可以采用各种字符集编码来编写JSP源文件,因此,JSP引擎将JSP源文件翻译
成Servlet源文件时,需要进行字符编码转换。
b) 如果JSP文件中没有说明它采用的字符集编码,JSP引擎将把它当作默认的ISO8859-1字符集编码处理。
3 如何解决JSP引擎翻译JSP页面时的中文乱码问题
通过page指令的contentType属性说明JSP源文件的字符集编码
page指令的pageEncoding属性说明JSP源文件翻译成servlet时的字符集编码
其实只用设置pageEncoding即可,此属性一旦设置好,翻译引擎会间接帮我们设置content-type属性.