Servlet中文乱码问题及解决方案剖析
2015-12-04 10:47
323 查看
在测试Servlet自动刷新页面这个例子的时候,无论我如何设置HelloWorld.java的编码格式或者在如下的代码中添入<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>都没办法解决乱码问题,乱码显示如下图:
out.println(docType +
"<html>\n" +
"<head><title>" + title + "</title></head>\n"+
"<body bgcolor=\"#f0f0f0\">\n" +
"<h1 align=\"center\">" + title + "</h1>\n" +
"<p>当前时间是:" + CT + "</p>\n");
http://write.blog.csdn.net/postedit
经过一番折腾和查找,找到了如下的靠谱解决方法:
在servlet的doGet方法中添加一句:
respnse.setHeader("content-type","text/html;charset=UTF-8");
于是输出了如下的正确形势:
![](https://img-blog.csdn.net/20151204104452370?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
分析出现乱码的原因:
汉字首先被封装在response对象中,由于浏览器和Web服务器之间不传递文本,在 HTML 4.01 中,ISO-8859-1 是默认的字符,然后就通过ISO-8859-1进行编码,而该编码不能正确编码汉字,所以浏览器最后输出了??这样的乱码。
--------------------------------分割线---------------------------------------------
将我参考的文章原样复制:
1.GBK包含GB2312,即如果通过GB2312编码后可以通过GBK解码,反之可能不成立;
2.java.nio.charset.Charset.defaultCharset() 获得平台默认字符编码;
3.getBytes() 是通过平台默认字符集进行编码;
在学习任何一门技术时,经常会有初学者遇到中文乱码问题,比如MySQL,是因为在安装时没有设置;而在Servlet中,也会遇到中文乱码问题;
比如:
OutputStream out = response.getOutputStream();
out.write(String );
输出中文时可能会出现乱码;
比如:
[java]
view plaincopy
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
OutputStream out = response.getOutputStream();
String data = "博客";
out.write(data.getBytes("UTF-8"));
}
输出乱码的问题是程序用UTF-8编码,而浏览器用GB2312解码,因此会出现乱码;
Servlet乱码分为request乱码和response乱码;
在网上很有效的解决方法是添加:
response.setCharacterEncoding("UTF-8");
解决不了,后来又搜到一条解决方法是:
respnse.setHeader("content-type","text/html;charset=UTF-8");
两句都填上,后来终于解决了这个问题;
其实我们应该思考一下本质;
我们这里先来说明一下错误的原因,下图是显示乱码的流程图:
![](http://hi.csdn.net/attachment/201201/28/0_13277566048xN8.gif)
response.setContentType("text/html;charset=UTF-8");
目的是为了控制浏览器的行为,即控制浏览器用UTF-8进行解码;
response.setCharacterEncoding("UTF-8"); 的目的是用于response.getWriter()输出的字符流的乱码问题,如果是response.getOutputStream()是不需要此种解决方案的;因为这句话的意思是为了将response对象中的数据以UTF-8解码后发向浏览器;
解决方案流程图:
![](http://hi.csdn.net/attachment/201201/28/0_1327764503s741.gif)
view plaincopy
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
String data = "博客";
out.println(data);
}
浏览器输出: ??
原因:"博客"首先被封装在response对象中,因为IE和WEB服务器之间不能传输文本,然后就通过ISO-8859-1进行编码,但是ISO-8859-1中没有“博客”的编码,因此输出“??”表示没有编码;
![](http://hi.csdn.net/attachment/201201/28/0_1327758492AjH3.gif)
而解决方案是:response.setCharacterEncoding("GB2312"); 设置response使用的码表
![](http://hi.csdn.net/attachment/201201/28/0_1327758281brO4.gif)
request请求分为post和get,对于不同的请求方式有不同的解决乱码的方案;
错误原因:
![](http://hi.csdn.net/attachment/201202/9/0_132875920805XK.gif)
解决方案:
![](http://hi.csdn.net/attachment/201202/9/0_1328759212mPoA.gif)
out.println(docType +
"<html>\n" +
"<head><title>" + title + "</title></head>\n"+
"<body bgcolor=\"#f0f0f0\">\n" +
"<h1 align=\"center\">" + title + "</h1>\n" +
"<p>当前时间是:" + CT + "</p>\n");
经过一番折腾和查找,找到了如下的靠谱解决方法:
在servlet的doGet方法中添加一句:
respnse.setHeader("content-type","text/html;charset=UTF-8");
于是输出了如下的正确形势:
分析出现乱码的原因:
汉字首先被封装在response对象中,由于浏览器和Web服务器之间不传递文本,在 HTML 4.01 中,ISO-8859-1 是默认的字符,然后就通过ISO-8859-1进行编码,而该编码不能正确编码汉字,所以浏览器最后输出了??这样的乱码。
--------------------------------分割线---------------------------------------------
将我参考的文章原样复制:
一、常识了解
1.GBK包含GB2312,即如果通过GB2312编码后可以通过GBK解码,反之可能不成立;
2.java.nio.charset.Charset.defaultCharset() 获得平台默认字符编码;
3.getBytes() 是通过平台默认字符集进行编码;
二、中文乱码出现
在学习任何一门技术时,经常会有初学者遇到中文乱码问题,比如MySQL,是因为在安装时没有设置;而在Servlet中,也会遇到中文乱码问题;
比如:
OutputStream out = response.getOutputStream();
out.write(String );
输出中文时可能会出现乱码;
比如:
[java]
view plaincopy
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
OutputStream out = response.getOutputStream();
String data = "博客";
out.write(data.getBytes("UTF-8"));
}
输出乱码的问题是程序用UTF-8编码,而浏览器用GB2312解码,因此会出现乱码;
Servlet乱码分为request乱码和response乱码;
三、response中文乱码
在网上很有效的解决方法是添加:
response.setCharacterEncoding("UTF-8");
解决不了,后来又搜到一条解决方法是:
respnse.setHeader("content-type","text/html;charset=UTF-8");
两句都填上,后来终于解决了这个问题;
其实我们应该思考一下本质;
问题1:
我们这里先来说明一下错误的原因,下图是显示乱码的流程图:
![](http://hi.csdn.net/attachment/201201/28/0_13277566048xN8.gif)
response.setContentType("text/html;charset=UTF-8");
目的是为了控制浏览器的行为,即控制浏览器用UTF-8进行解码;
response.setCharacterEncoding("UTF-8"); 的目的是用于response.getWriter()输出的字符流的乱码问题,如果是response.getOutputStream()是不需要此种解决方案的;因为这句话的意思是为了将response对象中的数据以UTF-8解码后发向浏览器;
解决方案流程图:
![](http://hi.csdn.net/attachment/201201/28/0_1327764503s741.gif)
问题2
问题代码如下:
[java]view plaincopy
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
String data = "博客";
out.println(data);
}
浏览器输出: ??
原因:"博客"首先被封装在response对象中,因为IE和WEB服务器之间不能传输文本,然后就通过ISO-8859-1进行编码,但是ISO-8859-1中没有“博客”的编码,因此输出“??”表示没有编码;
错误代码流程图:
![](http://hi.csdn.net/attachment/201201/28/0_1327758492AjH3.gif)
而解决方案是:response.setCharacterEncoding("GB2312"); 设置response使用的码表
解决方案流程图:
![](http://hi.csdn.net/attachment/201201/28/0_1327758281brO4.gif)
补充:通过<meta>标签模拟response头;
<meta http-equiv="content-type" content="text/html"/> 等价于 response.setContentType("text/html");四、request乱码问题
request请求分为post和get,对于不同的请求方式有不同的解决乱码的方案;
1.post请求乱码
错误原因:
![](http://hi.csdn.net/attachment/201202/9/0_132875920805XK.gif)
解决方案:
![](http://hi.csdn.net/attachment/201202/9/0_1328759212mPoA.gif)
2.get请求乱码
![](http://hi.csdn.net/attachment/201202/9/0_1328759222QfR3.gif)
相关文章推荐
- Ⅰ.14 如何处理测试脚本发生的异常
- Wi-Fi: Peer-to-Peer Services Technical Spec
- mysql-5.7.9-winx64 MySQL服务无法启动,服务没有报告任何错误的解决办法
- VS2010+Opencv-2.4.0的配置攻略
- Android控件之ListView与BaseAdapter
- Oracle11gR2学习笔记汇总
- 浏览器内核分类
- Dubbo架构设计详解
- 流式布局
- web.xml的一些个配置
- C\C++中的整形提升
- 装配置mysql-5.7.5-m15-winx64
- ssl 复制
- Bugfree 搭建
- 开源界何时不再玩捉迷藏游戏?
- JS运动--分享到空间代码样式
- 在android开发中使用multdex的方法-IT蓝豹为你整理
- 监理工程师岁月--神奇的张总监
- 记忆碎片
- erlang源码分析