当前位置: 移动技术网 > IT编程>开发语言>Java > JavaEE中用response向客户端输出中文数据乱码问题分析

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

2019年07月22日  | 移动技术网IT编程  | 我要评论

  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");

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网