PrintWriter 输出流中文乱码问题

目录

字符字节转换

失败案例

原因

解决方案

概述

解决方案一

解决方案二(推荐)

成功案例


字符字节转换

由于计算机中的数据都是以二进制形式存储的,当传输文本时,就会发生字符和字节之间的转换(通过查码表完成).

将字符转换成字节的过程称为编码,将字节转换成字符的过程称为解码.

如果编码和解码使用的码表不一致,就会导致乱码问题.

失败案例

使用字符输出流输出中文字符:

 import javax.servlet.*;
 import javax.servlet.http.*;
 import javax.servlet.annotation.*;
 import java.io.IOException;
 import java.io.PrintWriter;
 ​
 @WebServlet(name = "ChineseServlet", value = "/ChineseServlet")
 public class ChineseServlet extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         PrintWriter printWriter = response.getWriter();
         printWriter.write("中国");
     }
 ​
     @Override
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doGet(request, response);
     }
 }

出现??说明乱码:

原因

response对象的字符输出流在编码时采用的是ISO-8859-1的字符码表,

该码表不兼容中文,会将“中国”编码为“63 63”(在ISO-8859-1的码表中查不到的字符就会显示63)。

当浏览器对接收到的数据进行解码时,会采用默认码表GB2312,将ISO-8859-1码表编码的“63”解码为“?”,

因此浏览器将“中国”这个字符显示成了“??”

解决方案

概述

为了解决编码错误的问题,HttpServletResponse接口提供了一个setCharacterEncoding(),

该方法用于设置字符的编码方式.

例如:在案例代码输出字符前设置字符编码为UTF-8

 response.setCharacterEncoding("utf-8");

结果:

浏览器中显示的乱码虽然不是“??”,但也不是“中国”.

这是浏览器编码错误导致的,response对象的字符输出流设置的编码方式为UTF-8,而浏览器使用的解码方式是GB2312

这就是因为编码和解码使用码表不一致导致乱码.

对于浏览器编码问题,可以通过修改浏览器的编码方式解决,

但这样的做法仍然是不可取的,因为不能让用户每次都设置浏览器编码方式.

为此,HttpServletResponse接口提供了两种解决乱码的方案.

解决方案一

 // 设置HttpServletResponse使用UTF-8编码
 response.setCharacterEncoding("utf-8");
 ​
 // 通知浏览器使用utf-8解码
 response.setHeader("Content-Type", "text/html; charset = utf-8");

解决方案二(推荐)

 // 包含解决方案一的所有功能,相比之下更为简洁
 response.setContentType("text/html; charset = utf-8");

成功案例

 import javax.servlet.*;
 import javax.servlet.http.*;
 import javax.servlet.annotation.*;
 import java.io.IOException;
 import java.io.PrintWriter;
 ​
 @WebServlet(name = "ChineseServlet", value = "/ChineseServlet")
 public class ChineseServlet extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         // 方案二设置字符编码,解决中文字符乱码问题,必须放在PrintWriter输出流对象声明前,否则不会生效
         response.setContentType("text/html; charset = utf-8");
 ​
         PrintWriter printWriter = response.getWriter();
         printWriter.write("中国");
     }
 ​
     @Override
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doGet(request, response);
     }
 }

  • 29
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值