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

 更新时间:2014年10月26日 10:46:17   投稿:hebedich  
这篇文章主要介绍了JavaEE中用response向客户端输出中文数据乱码问题分析,需要的朋友可以参考下

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

相关文章

  • Java Web导出等比例图片到Excel的实现过程

    Java Web导出等比例图片到Excel的实现过程

    我们使用Java导出图片到Excel,打开成功导出的Excel一看,商品对应的图片都很规矩的按照我的设置铺满了整个单元格,但是,商品图片却都变形了,这样肯定是不行的,于是第一反应就是将图片等比例导出,所以本文本给大家介绍了如何使用Java Web导出等比例图片到Excel
    2023-11-11
  • Mybatis中自定义TypeHandler处理枚举的示例代码

    Mybatis中自定义TypeHandler处理枚举的示例代码

    typeHandler,是 MyBatis 中的一个接口,用于处理数据库中的特定数据类型,下面简单介绍创建自定义 typeHandler 来处理枚举类型的示例,感兴趣的朋友跟随小编一起看看吧
    2024-01-01
  • springboot配置druid连接池的方法示例

    springboot配置druid连接池的方法示例

    这篇文章主要介绍了springboot配置druid连接池的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • Java基础之反射

    Java基础之反射

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;反射是框架设计的灵魂,感兴趣的小伙伴可以参考阅读
    2023-03-03
  • 详解jeefast和Mybatis实现二级联动的问题

    详解jeefast和Mybatis实现二级联动的问题

    这篇文章主要介绍了详解jeefast和Mybatis实现二级联动的问题,本文通过图文实例相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • 通过实例了解Spring中@Profile的作用

    通过实例了解Spring中@Profile的作用

    这篇文章主要介绍了通过实例了解Spring中@Profile的作用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • 基于java HashMap插入重复Key值问题

    基于java HashMap插入重复Key值问题

    这篇文章主要介绍了基于java HashMap插入重复Key值问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Java一行代码搞定耗时性能追踪

    Java一行代码搞定耗时性能追踪

    在开发过程中,性能监控和调试是我们经常面对的问题,虽然市面上有许多成熟的性能监控工具,但有时我们需要一个轻量级、灵活且优雅的解决方案,下面我们就来看看Java如何搞定耗时性能追踪吧
    2024-11-11
  • SpringBoot整合MybatisPlus的基本应用指南

    SpringBoot整合MybatisPlus的基本应用指南

    MyBatis-Plus ,简称 MP,是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,下面小编就来和大家介绍一下SpringBoot整合MybatisPlus的一些基本应用吧
    2025-03-03
  • SpringBoot启动时自动执行sql脚本的方法步骤

    SpringBoot启动时自动执行sql脚本的方法步骤

    本文主要介绍了SpringBoot启动时自动执行sql脚本的方法步骤,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09

最新评论