1.Servlet的中文输出问题—》原理
浏览器接收到的中文字符并不是中文符号本身,而是它的某种字符集编码的数据。 浏览器必须使用正确的字符集编码进行查看,才能将它所接收到的数据显示为正确的中文字符。可以手动设置浏览器的编码,也可以在编写的时候就告诉理浏览器用什么编码来读取和显示。
当Servlet程序仅仅需要输出纯文本格式的响应正文时,通常应调用ServletResponse对象的getWriter方法返回一个PrintWriter对象,然后使用这个PrintWriter对象将文本内容写入到客户端。 Java程序中的字符文本在内存中是以unicode编码的形式存在的,PrintWriter对象在输出字符文本时,需要先将它们转换成其他某种字符集编码的字节数组后输出。ServletResponse对象的getWriter方法返回的PrintWriter对象默认使用ISO8859-1字符集编码进行Unicode字符串到字节数组的转换,由于ISO8859-1字符集中根本就没有中文字符,Unicode编码的中文字符将被转换成无效的字符编码后输出给客户端。
2.Servlet的中文输出问题—》办法
l ServletResponse接口中定义了setCharacterEncoding、setContentType等方法来指定ServletResponse.getWriter方法返回的PrintWriter对象所使用的字符集编码。
l 调用ServletResponse接口中定义的setContentType方法,在HTTP响应消息的Content-Type头字段中指定响应正文的字符集编码。
3.使用<meta>标签模拟响应消息头
l 问题:
利用HTTP消息的响应头字段,可以让浏览器完成各种有用的功能,但是,这需要通过编写WEB服务器端的程序来实现。如果不会服务器端编程的普通HTML页面制作者也想借助HTTP消息的响应头字段来实现一些特殊功能,他们该怎么办呢?
l 解决方案:
HTML语言中专门定义了<meta>标签的http-equiv属性来在HTML文档中模拟HTTP响应消息头,当浏览器读取到HTML文档中具有http-equiv属性的<meta>标签时,它会用与处理WEB服务器发送的响应消息头一样的方式来进行处理。
l 举例:
ü <metahttp-equiv="Expires" content="0">
ü <metahttp-equiv="Cache-Control" content="no-cache">
ü <metahttp-equiv="Pragma" content="no-cache">
ü <metahttp-equiv="Refresh"content="0;url=http://www.it315.org">
ü <metahttp-equiv="Content-Type" content="text/html;charset=GB2312">
4.一个例子具体分析乱码的各种情况和多种解决方法
packagecom.response; importjava.io.IOException; importjava.io.OutputStream; importjavax.servlet.ServletException; importjavax.servlet.http.HttpServlet; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; publicclass ResDemo1 extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { test5(response); } //没有乱码;调用方法getBytes()以及用获取字节的方法,默认是GB2312;浏览器默认也是GB231 public void test1(HttpServletResponseresponse) throws IOException { String str = "河北"; response.getOutputStream().write(str.getBytes()); } //手动的把字节改为UTF-8编码,使其造成错误,然后进行处理 public void test2(HttpServletResponseresponse) throws IOException { String str = "河北"; // 方法一:发送消息头,通知浏览器以UTF-8打开内容 //response.setHeader("Content-Type","text/html;charset=UTF-8"); //方法二:调用ServletResponse接口中定义的setContentType方法 response.setContentType("text/html;charset=UTF-8"); response.getOutputStream().write(str.getBytes("UTF-8")); } // 不发送http头,而是发送了一段html内容来控制浏览器以utf-8打开。 public void test3(HttpServletResponseresponse) throws IOException { String str = "北京"; OutputStream out =response.getOutputStream(); out.write("<metahttp-equiv='content-type'context='text/html;charset=UTF-8'>".getBytes()); out.write(str.getBytes()); } // 采用字符输出流,response默认的编码是iso8859-1, public void test4(HttpServletResponseresponse) throws IOException { /* 把response的编码改为UTF-8; response.setCharacterEncoding("UTF-8"); 告诉浏览器,以UTF-8显示,这种设置可以不用设置response的编码 response.setHeader("Content-Type","text/html;charset=UTF-8");*/ //这一种设置相当于上面的两种设置 response.setContentType("text/html;charset=UTF-8"); response.getWriter().print("杨凯"); } //用OutputStream输出数字时出现乱码解决:直接输出一个整数,会乱码。 public void test5(HttpServletResponseresponse) throws IOException{ /*下面两种方法输出会乱码或不输出 response.getWriter().write(14); response.getOutputStream().write(14); */ //方法一:可以直接这么输出 //response.getWriter().print(14); //方法二:加一个双引号,java虚拟机会将数字一起当做字符串 response.getOutputStream().write((14+"").getBytes()); } public void doPost(HttpServletRequestrequest, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }