JavaEE中用response向客户端输出中文数据乱码问题分析_java

  Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象,和代表响应的response对象。request和response对象既然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向客户机输出数据,只需要找response对象就行了。

复制代码 代码如下:

 package com.yyz.response;
 import java.io.IOException;
 import java.io.OutputStream;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 //输出中文的问题
 public class ResponseDemo extends HttpServlet {
     public void doGet(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
         String data = "中国";
         OutputStream out = response.getOutputStream();
         out.write(data.getBytes());
         /**
          *     out.write(data.getBytes());这句代码涉及两次查阅码表。
          *    "中国"从字符数据变成字节数据的时候,会查阅gb2312码表。
          *    数据发送到浏览器端要显示的时候,需要再次查阅码表,这时查阅的码表与浏览器的设置有关。
          */
         }
     public void doPost(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
            doGet(request,response);
     }
 }

浏览器编码设置为GB2312时的测试结果:

浏览器编码设置为UTF-8时的测试结果:

  为了让我们的网站能被国外用户访问,我们在将字符数据变成字节数据时,要指定转换的码表为UTF-8。但这时如果浏览器以GB2312打开,又会出现乱码问题。虽然可以通过改变浏览器的设置来解决这个乱码问题,但不利于增强用户体验。因而我们需要用程序告诉浏览器查阅何种码表显示数据。

复制代码 代码如下:

 package com.yyz.response;
 import java.io.IOException;
 import java.io.OutputStream;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 //输出中文的问题
 public class ResponseDemo extends HttpServlet {
     public void doGet(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
         //在服务器端,数据是以哪个码表输出的,那么就要控制浏览器以哪个码表打开。
         String data = "中国";
         response.setHeader("content-type", "text/html;charset=UTF-8");
         OutputStream out = response.getOutputStream();
         out.write(data.getBytes("UTF-8"));
     }
     public void doPost(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
            doGet(request,response);
     }
 }

 多学一招:

使用HTML语言里面的<meta>标签来控制浏览器行为。

<meta http-equiv="Content-type'' content=''text/html;charset=UTF-8">
http-equiv模拟了HTTP的响应头,告诉浏览器以UTF-8的码表打开。真正的响应头优先于用http-equiv模拟的响应头。

 实际开发中,服务器向浏览器写文本数据应该用字符流。但是通过response的getWriter方法拿到的字符流默认的码表是ISO8859-1,这张码表里是没有中文对应的编码的,因而会把?对应的编码发送给浏览器,浏览器打开后全是问号。通过response的setCharacterEncoding可以修改服务端发送数据时查阅的码表。

复制代码 代码如下:

 package com.yyz.response;
 import java.io.IOException;
 import java.io.PrintWriter;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 //输出中文的问题
 public class ResponseDemo extends HttpServlet {
     public void doGet(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
         //在服务器端,数据是以哪个码表输出的,那么就要控制浏览器以哪个码表打开。
         String data = "中国";
         response.setHeader("content-type", "text/html;charset=UTF-8");
         response.setCharacterEncoding("UTF-8");
         PrintWriter out = response.getWriter();
         out.write(data);
     }
     public void doPost(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
            doGet(request,response);
     }
 }

这里有几个小细节需要注意:
1. response.setCharacterEncoding("UTF-8");需要写在PrintWriter out = response.getWriter();的前面。拿到字符流后再设置编码是没有用的。

2. response.setHeader("content-type", "text/html;charset=UTF-8");有一种更为简单的写法response.setContentType("text/html;charset=UTF-8");。

3.response.setContentType("text/html;charset=UTF-8");这句代码其实有两个作用:通知response以UTF-8输出和浏览器以UTF-8打开。即等价于response.setHeader("content-type", "text/html;charset=UTF-8");和response.setCharacterEncoding("UTF-8");两句代码。

4.通过以上阅读,读者应该能明白为什么response.getOutputStream.write(1);这句代码在浏览器的输出不是1。因为浏览器是一个文本编辑器,收到数据后会拿着1去查码表,然后显示对应字符。想在浏览器输出数字,应该把数字变成字符串,response.getOutputStream.write((1+"").getBytes());.

用OutputStream(字节流)发送数据:
1、response.getOutputStream().write(“中国”.getBytes());//以默认编码发送数据
2、response.getOutputStream().write("中国".getBytes("UTF-8"));//以UTF-8编码发送数据,浏览器(默认用GB2312)会出现乱码

解决办法:
2.1通过更改浏览器的编码方式:IE/”查看”/”编码”/”UTF-8”(不可取)
2.2通过设置响应头告知客户端编码方式:response.setHeader(“Content-type”, “text/html;charset=UTF-8”);//告知浏览器数据类型及编码
2.3通过meta标签模拟请求头:out.write("<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />".getBytes());
2.4通过以下方法:response.setContentType("text/html;charset=UTF-8");

时间: 2024-10-03 16:21:18

JavaEE中用response向客户端输出中文数据乱码问题分析_java的相关文章

解决asp.net core在输出中文时乱码的问题_实用技巧

前言 作为一个.NET Web开发者,我最伤心的时候就是项目开发部署时面对Windows Server上贫瘠的解决方案,同样是神器Nginx,Win上的Nginx便始终不如Linux上的,你或许会说"干嘛不用windows自带的NLB呢",那这就是我这个小鸟的从众心理了,君不见Stack Overflow 2016最新架构中,用的负载和缓存技术也都是采用在Linux上已经成熟的解决方案吗.没办法的时候找个适合的解决办法是好事,有办法的时候当然要选择最好的解决办法. 所幸,.ASP.NE

我用webstrom写nodejs,在console时输出中文有乱码,请问是怎么回事

问题描述 我用webstrom写nodejs,在console时输出中文有乱码,请问是怎么回事 我用webstrom写nodejs,在console时输出中文有乱码,请问是怎么回事 输出的结果如图 请大神帮忙解答一下 解决方案 http://blog.csdn.net/hongweigg/article/details/8760372

ext中form提交的数据中文数据乱码

问题描述 ext中form提交的数据中文数据乱码.我有一个程序,如果是添加信息中含有中文就不会乱码,如果是修改信息中含有中文就是乱码.这是怎么回事 解决方案 解决方案二:前台页面用utf-8,后台弄个过滤器也用utf-8就不会有问题了

cmd中MySQL中文数据乱码问题解决方法_Mysql

我的MySQL是默认utf8编码的,所建数据库也是设置utf8编码,使用程序可以新增中文数据,在cmd中使用SQL语句新增数据则报类似Incorrect string value: '\xB2\xE2\xCA\xD4' for column 'title' at row 1错误,而使用SQL语句查询出之前程序所新增中文数据都是乱码的. 右击在cmd界面上面边框→属性→选项 ,查看cmd的编码方式是是GBK,并不是utf-8. 其实数据库内部是没有乱码的,只是和cmd的编码方式不一样,在cmd呈现

关于win7系统 vs2010下的C语言 输出中文 是乱码问题

将下面的代码复制到记事本里吧,另存为扩展名为".reg"的文件,双击导入注册表就完成了 CMD 环境中汉字输入和汉字显示的恢复. Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Console\%SystemRoot%_system32_cmd.exe] "CodePage"=dword:000003a8 小说明一下: 十六进制"000003a8"或十进制"936"

MySQL中文汉字乱码问题分析

解决网页中乱码的问题,在程序查询时定义  代码如下 复制代码 db =  mysql _connect("localhost", "user","password");  mysql_select_db("message",$db); mysql_query("SET NAMES 'utf8'",$db);   将所有的环境都设置为utf8编码,你可以在sqlYog的查询窗口中使用 1. SHOW VARI

Java中FTPClient上传中文目录、中文文件名乱码问题解决方法_java

问题描述:   使用org.apache.commons.net.ftp.FTPClient创建中文目录.上传中文文件名时,目录名及文件名中的中文显示为"??". 原因:   FTP协议里面,规定文件名编码为iso-8859-1,所以目录名或文件名需要转码. 解决方案: 1.将中文的目录或文件名转为iso-8859-1编码的字符.参考代码: 复制代码 代码如下:    String name="目录名或文件名";    name=new String(name.ge

android工程输出中文乱码 Java工程正常

问题描述 android工程输出中文乱码 Java工程正常 新建android工程用EditText输入数据,异或加密输出,输出中文为乱码,新建Java工程输出正常,跪求大神指点.百度都快翻烂了./(ㄒoㄒ)/~~ 解决方案 你输出密文时没有指定解码格式?android和java工程默认使用的解码可能不同 解决方案二: 应该是项目制定的编码不同吧? 解决方案三: 转码试试看能正常么有可能是两面的编码格式不一样

MYSQL存储数据乱码

mysql的字符集设置有多个层级,在mysql中存储中文,如果不能正确设置字符集,很容易出现数据乱码.今天就有一个用户反馈他数据库中的数据下午1点多开始出现了乱码.在这里,我分享下具体问题的排查过程,以及解决的办法.   (1)  排除客户端设置导致的显示乱码 如果用户设置的mysql character_set_client跟客户端显示的字符集不一致,很容易导致中文数据乱码. 设置session字符集为utf8:set names utf8,设置客户端显示字符集为utf8,然后从表中selec