在前面的网页中的编码与乱码系列中(一、二、三、四、五),曾多次提到使用 servlet 方式构建的动态响应流,不过在那里都是直接使用字节流的方式,不过,更为常见的方式是使用字符流。而在前面,又谈到了 Java 字节流与字符流的话题(一、二、三、四)。

有了前面的基础,现在来说下 Java servlet 中使用字符流,也即是 PrintWriter 时的编码与乱码问题。

回顾字节流的情形

先回顾一下,在之前的字节流响应中,我们使用 String.getBytes 方法,然后总是显式传入编码的参数,使它与 meta 中或者 header 的声明一致。比如这样:

或者这样:

只要保持了一致,就不用担心发生乱码的问题。

使用 PrintWriter 字符流,缺省编码

现在假如使用 PrintWriter 来作为响应呢?比如这样:

代码中并没有显式传入什么编码的参数,不像 String.getBytes 那样。另一方面,我们知道,字符流最终还是要转换成字节流,可是它到底使用了什么编码呢?是不是 Charset.defaultCharset 中的值呢?

就以上述代码为例,假如现在在浏览器中查看,会发现结果是这样的:

可见 defaultCharset 缺省是 utf-8,前面说过,这其实来自于启动 tomcat server 时所传入的参数 –Dfile.encoding,(见前面篇章 Java 字节流与字符流(3)):

但汉字却没有正确输出,可见 PrintWriter 并没有采用这个缺省值。查看 header 中的响应:

也没有任何编码的指示。

虽然 meta 中声明是 utf-8,输出的缺省字符集的值也是 utf-8,可是从最终结果不难看出 PrintWriter 并没有采纳这个值来转换字节流。(实际上它根本不会试图去理解这个)。

看一看它的文档说明,会发现情况有点不一样:

原来没有指定时,PrintWriter 不是用 Charset.defaultCharset 中的值,而是用 response.getCharacterEncoding 方法中所返回的值,而没有指定的话,那个方法其实就返回一个缺省值:ISO-8859-1。

再看看 getCharacterEncoding 方法:

可以看到它的值又是来源于显式的 response.setCharacterEncoding 或 response.setContentType 方法,或者是隐式的 setLocale 方法。(显式的具有更高的优先级)假如没有,就用缺省的 ISO-8859-1。

它还提到 RFC 2047 标准,打开看看,是关于 MIME 中非 ASCII 文本的消息头扩展(MIME (Multipurpose Internet Mail Extensions) Part Three:  Message Header Extensions for Non-ASCII Text)的。文中有一处提到如果字符集编码缺失,推荐用 iso8859 系列:

注意这里没有明说是 iso-8859-1,它说的是 iso-8859-*,不过 servlet 最终采用的是 iso-8859-1.

所以现在清楚了,缺省用 iso-8859-1,可以用 getCharacterEncoding 得到它的值,不过 iso 不支持中文字符,所以响应流中不能出现中文:

结果是这样:

使用 PrintWriter 字符流,显式指定编码

按照前面说的,可以在 write 之前使用 setCharacterEncoding 等方法指定编码:

这样就 OK 了:

要注意,这种情况下,response header 中仍然没有 charset 信息,所以要在 meta 中指定。

也可以用 setContentType (或前面一直用的 setHeader,其实两者是等价的):

也能达成同样效果:

这种情况下,response header 中包含 charset 信息,所以前面的代码中可以省略在 meta 中的声明:

那么,现在我们明白了,PrintWriter 的缺省与普通字符流的缺省是不同的,机制有所差别。

使用普通字符流,缺省编码

当然如果你一定要用普通字符流,也是可以的,但最后需要主动 flush:

这时的缺省就是 Charset.defaultCharset 中的值了,这里把它拼在了 meta 和最终的输出中,响应也是正常的:

结果是 utf-8。跟前面所说的 tomcat server 启动时参数的值一致。

使用普通字符流,显式指定编码

如果不打算用缺省,那就直接指定:

结果同样是 OK 的:

当然,一般还是建议使用 PrintWriter 来输出,而即便你一定要用普通字符流,也最好不要用缺省。

java writer 乱码_Java servlet 使用 PrintWriter 时的编码与乱码相关推荐

  1. java printwriter乱码_Java servlet 使用 PrintWriter 时的编码与乱码的示例代码

    在前面的网页中的编码与乱码系列中,曾多次提到使用 servlet 方式构建的动态响应流,不过在那里都是直接使用字节流的方式,不过,更为常见的方式是使用字符流.而在前面,又谈到了 Java 字节流与字符 ...

  2. java读txt文件乱码_java读取txt文件时出现中文乱码怎么解决

    java读取txt文件时出现中文乱码怎么解决 发布时间:2020-06-25 15:27:31 来源:亿速云 阅读:105 作者:Leah java读取txt文件时出现中文乱码怎么解决?针对这个问题, ...

  3. java控制台中文乱码_java用控制台输出时出现乱码怎么办

    java用控制台输出时出现乱码怎么办 发布时间:2020-06-26 16:00:24 来源:亿速云 阅读:113 作者:Leah java用控制台输出时出现乱码怎么办?相信很多没有经验的人对此束手无 ...

  4. java 会话共享_java – servlet如何工作?实例化,会话,共享变量和多线程

    假设,我有一个拥有大量servlet的Web服务器.对于在这些servlet之间传递的信息,我正在设置会话和实例变量. 现在,如果有2个或更多用户向此服务器发送请求,那么会话变量会发生什么?它们对所有 ...

  5. java微信公众号中文乱码_java微信公众平台开发回复中文消息乱码解决方案

    如上图所示,中文乱码,解决方法: 1,找到公众管理平台服务器配置的url请求地址对应的类(java是一个普通的servlet类). 2,在doPost方法中加入以下代码: // 将请求.响应的编码均设 ...

  6. java 读取txt乱码_java 逐行读取txt文本如何解决中文乱码

    java读取txt文本中如含有中文,可能会出现乱码,解决方案是: 1.要统一编码,java工程的编码,txt文本编码,java工程中的java文本编码都统一为utf-8: 2.利用 InputStre ...

  7. java word 乱码_java另存word时出现乱码怎么办

    java另存word时出现乱码怎么办 发布时间:2020-04-07 11:05:31 来源:亿速云 阅读:92 作者:小新 这篇文章主要为大家详细介绍了java另存word时出现乱码怎么办,文中示例 ...

  8. java 保存mysql 乱码_java mysql 汉字存入时乱码

    java mysql 汉字存入时乱码 从网络摘抄到的解决方法-- 解决方法二: 连接mysql时(无论在从mysql读还是取数据的情况),指定使用的编码方式为utf-8,具体代码如下 //装载mysq ...

  9. java邮件附件名称乱码_Java邮件开发(三):解决附件名为乱码及显示友好名称

    遗留的问题有以下两个: 1.附件的名称只能为英文,中文乱码 2.友好名称的显示. 我们使用163等邮箱发送邮件时,我们经常可以看到收件人一栏中会是:张益达 这种方式.在上一版本的代码中并没有使用这样的 ...

  10. java运行时_java编译时与运行时概念与实例详解

    Java编译时与运行时很重要的概念,但是一直没有明晰,这次专门博客写明白概念. 基础概念 编译时 编译时顾名思义就是正在编译的时候.那啥叫编译呢?就是编译器帮你把源代码翻译成机器能识别的代码.(当然只 ...

最新文章

  1. vss error reading from file 解决方法
  2. 人类第一次将42写成3个整数的立方和,最后一个100以内的自然数告破
  3. 一个使用:focus-within伪类实现的button选中动画效果
  4. java 多态性 接口_Java中的多态性和接口
  5. 【渝粤教育】电大中专建设工程法规1作业 题库
  6. 7安装sql cent os server_Cent OS 7 编译安装 My SQL 5.7
  7. shell脚本:判断本地和远程文件是否存在
  8. 自然语言处理NLP(二)
  9. console application
  10. 傅里叶热传导定律【Fourier's Law of Heat Conduction】
  11. Unity零基础到入门 ☀️| Unity下载安装---使用UnityHub下载各个版本的Unity(收藏)
  12. Unity的lookRotation和lookAt的区别理解,是什么意思。
  13. 在类方法中可 用this来调用本类的类方法
  14. java jtextarea.setfont,Java JTextArea用法
  15. 女程序员,作程序员还是作女人?
  16. 麻省理工大学公开课 离散数学
  17. 感悟开发.Net代码自动生成器,为软件起个好名字
  18. 用Flutter做桌上弹球?聊聊绘图(CanvasCustomPaint)API
  19. ZZULI2483: 小新三连(三):小新在求助
  20. 饼图中显示百分比方法

热门文章

  1. ElementUI:没有dist文件夹,vue项目打包后字体图标失效,变成小方框解决方案
  2. Cesium:本地node运行cesium报错Must use import to load ES Module
  3. Javascript:ES6语法简述
  4. matlab 马丢函数,振幅调制产生马丢光束的方法与流程
  5. Linux下防止rm -frv 删除错误的解决办法
  6. Neo4j如何对大量数据-(千万节点及以上数据)进行加载入库
  7. opencv图像分析与处理(11)- 频率域滤波消除周期噪声
  8. 深度学习DeBug小笔记(一)——visdom服务启动时提示Downloading scripts, this may take a little while解决办法
  9. 拦截JQuery的ajax
  10. 老调重弹:对kvo的封装思路