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

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

response常见应用(一):向客户端输出中文数据

 1 package com.yyz.response;
 2
 3 import java.io.IOException;
 4 import java.io.OutputStream;
 5
 6 import javax.servlet.ServletException;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 //输出中文的问题
11 public class ResponseDemo extends HttpServlet {
12
13     public void doGet(HttpServletRequest request, HttpServletResponse response)
14             throws ServletException, IOException {
15         String data = "中国";
16         OutputStream out = response.getOutputStream();
17         out.write(data.getBytes());
18         /**
19          *     out.write(data.getBytes());这句代码涉及两次查阅码表。
20          *    "中国"从字符数据变成字节数据的时候,会查阅gb2312码表。
21          *    数据发送到浏览器端要显示的时候,需要再次查阅码表,这时查阅的码表与浏览器的设置有关。
22          */
24         }
25
26     public void doPost(HttpServletRequest request, HttpServletResponse response)
27             throws ServletException, IOException {
28            doGet(request,response);
29     }
30
31 }

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


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

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

 1 package com.yyz.response;
 2
 3 import java.io.IOException;
 4 import java.io.OutputStream;
 5
 6 import javax.servlet.ServletException;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 //输出中文的问题
11 public class ResponseDemo extends HttpServlet {
12
13     public void doGet(HttpServletRequest request, HttpServletResponse response)
14             throws ServletException, IOException {
15         //在服务器端,数据是以哪个码表输出的,那么就要控制浏览器以哪个码表打开。
16         String data = "中国";
17         response.setHeader("content-type", "text/html;charset=UTF-8");
18         OutputStream out = response.getOutputStream();
19         out.write(data.getBytes("UTF-8"));
20     }
21
22     public void doPost(HttpServletRequest request, HttpServletResponse response)
23             throws ServletException, IOException {
24            doGet(request,response);
25     }
26 }

多学一招:

使用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可以修改服务端发送数据时查阅的码表。

 1 package com.yyz.response;
 2
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5
 6 import javax.servlet.ServletException;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 //输出中文的问题
11 public class ResponseDemo extends HttpServlet {
12
13     public void doGet(HttpServletRequest request, HttpServletResponse response)
14             throws ServletException, IOException {
15         //在服务器端,数据是以哪个码表输出的,那么就要控制浏览器以哪个码表打开。
16         String data = "中国";
17         response.setHeader("content-type", "text/html;charset=UTF-8");
18         response.setCharacterEncoding("UTF-8");
19         PrintWriter out = response.getWriter();
20         out.write(data);
21     }
22
23     public void doPost(HttpServletRequest request, HttpServletResponse response)
24             throws ServletException, IOException {
25            doGet(request,response);
26     }
27 }

这里有几个小细节需要注意:
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());.

时间: 2024-11-12 16:16:57

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

WEB应用常见中文数据乱码问题总结

在实际工作中,会遇到很多中文数据的乱码的问题,之所以会产生乱码,就是因为服务器和客户端沟通的编码不一致造成的,因此解决的办法是:在客户端和服务器之间设置一个统一的编码,之后就按照此编码进行数据的传输和接收. 1.以POST方式提交表单中文参数的乱码问题 客户端是以UTF-8字符编码将表单数据传输到服务器端,因此服务器也需要设置以UTF-8字符编码进行接收,服务器可以直接使用从ServletRequest接口继承而来的"setCharacterEncoding(charset)"方法进行

提交中文数据乱码问题总结

提交中文数据乱码问题总结 1.如果提交方式为post,想不乱码,只需要在服务器端设置request对象的编码即可,客户端以哪种编码提交的,服务器端的request对象就以对应的编码接收,比如客户端是以UTF-8编码提交的,那么服务器端request对象就以UTF-8编码接收(request.setCharacterEncoding("UTF-8")) 2.如果提交方式为get,设置request对象的编码是无效的,request对象还是以默认的ISO8859-1编码接收数据,因此要想不

perl输出中文有乱码

测试文件的时候发现输出中文有乱码,所以学习了一下perl的Encode原理.现做一下总结:perl的基础知识:在Perl看来, 字符串只有两种形式.一种是octets, 即8位序列, 也就是我们通常说的字节数组.另一种utf8编码的字符串, perl管它叫string. 也就是说: Perl只认识两种编码: Ascii(octets)和utf8(string). 所以输出时候出现乱码,应该把utf8编码转为用户能够接受的形式.例如中文用gb2312. my $s=":<中文关键词>=

笨鸟先飞之Java--MySql中文数据乱码为哪般???

从开始敲drp到现在的hibernate,中文数据乱码无时无刻不"陪伴"在我的身边: 图一:在drp的分销商模块,每次修改区域虽然返回修改成功,但是每次读取到的中文数据都是"???"的字符串,但数字和字母的数据却不受影响. 图二:不管是drp还是hibernate项目,通过执行sql或者hql语句插入中文数据的,都会呈现图中的景象,甚是无语...... 但被它困扰了这么久,我也算"久病成医",今天就一起来给Java项目医治一下中文数据乱码的这个大

CrossApp之VS2013不能输出中文,乱码,附加源码(一)

VS2013可以使用iconv,也可以使用宽字节的方式来处理. 代码才是王道,直接贴了... // // UTF8ToGBK.h // UTF8ToGBK // // Created by kevin. // #pragma once #include <iostream> #include <stdio.h> //string是c++ 的头文件,其内包含了一个string类,string s1就是建立一个string类的对象 #include <string> //c

Servlet向客户端发送中文数据的编码情况

(更多内容请关注本人微信订阅号:it_pupil) 本文讲述服务端servlet向客户端浏览器发送中文数据的编码情况,需要抓住下面几点: 输出流发送数据,必须是以字节形式传输的.也就是说,如果你在服务端定义一个字符串,那么servlet要先编码成字节数组,再发送到客户端. 客户端浏览器在收到字节码数据时,需要将其解码成字符串显示出来. 在服务端,如果你使用的是字节流,那么只需要注意两点:  拿到字符串,以特定形式编码成字节数组(如UTF-8).(字节数组是你人工转换的) 告诉浏览器,以相同方式解

MySQL插入中文数据乱码问题

一.MySQL插入中文不乱码5中方法小结 方法一:登录mysql,先做“set names latin1;”,然后再执行更新语句或执行语句文件. 方法二:在aql文件中指定set names latin1; 然后登录mysql,通过如下命令执行. 方法三:在sql文件中指定set names latin1; 然后通过mysql命令导入数据 方法四:通过指定mysql命令的字符集参数实现--default-character-set=latin1 方法五:在配置文件里设置客户端及服务端相关参数 不

关于hibernate插入mysql数据库中文数据乱码处理

这几天在学习hibernate,在程序中将利用hibernate将数据插入的mysql数据库的时候,发现出现了中文乱码,在网上搜索了好长时间,大概的解决方法都是修改my.ini的配置文件,修改为gbk,但是插入数据还是出现乱码的情况.不过最后还是解决了.下面就说一下解决的方法. 1.找到MySql Server Instance onfiguration Wizard管理器,重新配置mysql.如图.前面的配置可以一路下一步,到了图中这一步要修改语言为gbk. 2.要删除之前建立的数据库,重新利

从内存中写入mysql中文数据乱码解决

一. 问题 数据库编码:utf8 mysql> create database dbnameDEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; 表编码:utf8 drop table if exists `test`; create table `test` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', `name` varchar(50) default '', `create