HTTP BODY编码问题(中文字符乱码)

2018-10-18  本文已影响23人  李逍遥JK

Servlet返回数据的时候,通过response.getServletOutputStream获取ServletOutputStream返回到前端页面时没有出现乱码

        // 打印到浏览器未出现乱码
        ServletOutputStream pw = servletResponse.getOutputStream();
        pw.write(new String("UG中午").getBytes());
        pw.flush();
        pw.close();
1-1
原因是new String("UG中午").getBytes()使用的是系统默认的编码,此时是GBK,String.getBytes()的源码如下所示:
 static byte[] encode(char[] ca, int off, int len) {
        // Charset.defaultCharset()默认读取还是配置的语言编码;也是就是系统的;
        String csn = Charset.defaultCharset().name();
        try {
            // use charset name encode() variant which provides caching.
            return encode(csn, ca, off, len);
        } catch (UnsupportedEncodingException x) {
            warnUnsupportedCharset(csn);
        }
        try {
            return encode("ISO-8859-1", ca, off, len);
        } catch (UnsupportedEncodingException x) {
            // If this code is hit during VM initialization, MessageUtils is
            // the only way we will be able to get any kind of error message.
            MessageUtils.err("ISO-8859-1 charset not available: "
                             + x.toString());
            // If we can not find ISO-8859-1 (a required encoding) then things
            // are seriously wrong with the installation.
            System.exit(1);
            return null;
        }
    }

到了浏览器使用的解码也是GBK所以是正常的。不过在开发中这里还是建议设置成UTF-8.

----------------------------------------

但是使用PrintWriter打印时候,出现了乱码,解决办法是加上servletResponse.setContentType("application/json; charset=utf-8");
并且将response.setCharacterEncoding(“UTF-8”)写在servletResponse.getWriter()前面

        // 告诉浏览器用UTF-8解码  不加会出现乱码
        servletResponse.setContentType("application/json; charset=utf-8");
        
        // 这句写上了可能会也没有效果:
        // 原因:  response.setCharacterEncoding("UTF-8")语句执行之前执行了response.getWriter()语句。
        // 所以这句应该写在servletResponse.getWriter()前面
        servletResponse.setCharacterEncoding("UTF-8");
        PrintWriter pw1 =servletResponse.getWriter();
        pw1.write("C中午");
        pw1.flush();
        pw1.close();

分析PrintWriter出现乱码的原因:当通过Reponse返回给客户的时候,这个过程需要先进行编码,再到浏览器进行解码。编码字符集可以通过reponse.setCharacterEncoding来设置,它将会覆盖request.getCharacterEncoding的值,并通过HeaderContentType返回到客户端,浏览器接收到的返回的Socket流时将通过Content-Typecharset来解码。

默认的优先级从高到底如下:

1.reponse.setCharacterEncoding("UTF-8")设置编码格式
2.通过HTTP HeaderContent-Typecharset设置,如果没有进行第二步;
3.通过HTMLde <meta HTTP-equiv="Content-Type" content="text/html; charset="GBK" />中的charset来解码
4.如果上面的都未定义,那么浏览器通过默认的编码器解码

1-2 contentType中的charset
上一篇下一篇

猜你喜欢

热点阅读