目录
字符字节转换
由于计算机中的数据都是以二进制形式存储的,当传输文本时,就会发生字符和字节之间的转换(通过查码表完成).
将字符转换成字节的过程称为编码,将字节转换成字符的过程称为解码.
如果编码和解码使用的码表不一致,就会导致乱码问题.
失败案例
使用字符输出流输出中文字符:
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); } }