著作权归作者所有。

商业转载请联系作者获得授权,非商业转载请注明出处。

链接:https://stazxr.cn/2024/12/05/JDK-18-以上使用标准输出流中文输出乱码问题/

来源:終わり群星

问题描述

起因是 tomcat 调用servlet输出的System.out.println(也就是所说的控制台输出流)中文乱码,但是其他输出没有受到影响。

问题分析

运行环境:JDK 21, Tomcat 10

我所有的代码都是UTF-8编码的,而且在IDEA中设置了UTF-8编码。

并且Tomcat也配置了-Dfile.encoding=UTF-8选项

通过查看System.out的编码方式,发现是GBK,但是在控制台的编码方式是UTF-8

System.out.println(System.out.charset());   // System.out.charset()方法自jdk18起
// output: GBK

使用jdk17的时候没有问题,但是使用jdk21就会出现乱码问题。

解决方案

参考JEP 400: UTF-8 by Default (openjdk.org)通过调用getProperty方法获取默认字符集

System.out.println("Java Runtime version " + System.getProperty("java.runtime.version"));
System.out.println("----------------------------------------------------------");
//全局默认编码 JDK21是UTF
System.out.println("Charset.defaultCharset() = " + Charset.defaultCharset());
//默认文件的编码,这个应该是字节码文件
System.out.println("System.getProperty(\"file.encoding\") = " + Charset.defaultCharset().displayName());
//获取的是本地的字符集编码,中文windows系统应该是GBK
System.out.println("System.getProperty(\"native.encoding\") = " + System.getProperty("native.encoding"));
System.out.println("System.getProperty(\"sun.jnu.encoding\") = " + System.getProperty("sun.jnu.encoding"));
//这个是输出流的默认字符集编码
System.out.println("System.getProperty(\"sun.stdout.encoding\") = " + System.getProperty("sun.stdout.encoding"));
//这个是错误流的默认编码
System.out.println("System.getProperty(\"sun.stderr.encoding\") = " + System.getProperty("sun.stderr.encoding"));
//console默认编码
System.out.println("System.console().charset() = " + System.console().charset());
//当前输出流的编码
System.out.println("System.out.charset() = " + System.out.charset());
System.out.println("----------------------------------------------------------");

在一般的情况下System.getProperty("sun.stdout.encoding")System.getProperty("sun.stderr.encoding")的值是UTF-8,但是在Tomcat中是null

tomcat 10 不会指定输出流的字符编码

所以我们需要在启动tomcat的时候指定输出流的字符编码

是在启动配置中的 VM options 添加参数:

-Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8

这种方法只能解决所设置程序的编码问题,若需解决 Javadoc 的乱码,则需在-D前添加-J。

-J-Dstdout.encoding=UTF-8 -J-Dstderr.encoding=UTF-8

总结

乱码问题只出现在jdk18及以上的版本,因为Java 18 中将默认编码改为了 UTF-8,但没有改动System.out和System.err的编码。

所以使用jdk17没有问题,但是在使用jdk21就会出现乱码问题。

只要在 VM options 中添加 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 即可设置输出流的编码。

参考

写在最后

JDK 18 及以上使用标准输出流中文输出乱码问题的更多相关文章

  1. 解决VS Code编译调试中文输出乱码

    最近尝试用VS Code配置了C和C++的编译调试环境,结果遇到了中文输出乱码问题,查阅网上竟然还没有相关问题,有怀疑是mingw中文支持问题,但最后证明是VS Code编码问题. 解决方案: 文件- ...

  2. qtcreator_process_stub中文输出乱码

    使用qt运行程序输出中文,全都变成了□,让人很头疼,百度了很久,找了一些解决方案都是: 用vim打开x11-common,在控制台输入 vim /etc/X11/Xresources/x11-comm ...

  3. 控制台程序的中文输出乱码问题(export LC_CTYPE=zh_CN.GBK,或者修改/etc/sysconfig/i18n为zh_CN.GBK。使用setlocale(LC_CTYPE, "");会使用默认办法。编译器会将源码做转换成Unicode格式,或者指定gcc的输入文件的编码参数-finput-charset=GBK。Linux下应该用wprintf(L"%ls/n",wstr))

    今天发现用securecrt登陆时,gcc编译出错时会出现乱码,但直接在主机的窗口界面下用Shell编译却没有乱码.查看了一下当时的错误描述,发现它的引号是中文引号,导致在SecureCRT中显示出错 ...

  4. python--ulipad控制台中文输出乱码

    ulipad用起来顺手,而不尽人意的地方时,它不能正确输出中文.而且有人指出这和文件的编码没关系,所以将”设置“选项里”缺省文档编码“修改为”utf-8“也无济于事.为了解决这个问题,我在网上搜了搜, ...

  5. Code:Blocks中文输出乱码解决方法

    0x01 问题描述 将CB的编码格式设置为UTF-8之后,在CMD窗口输出中文乱码. 0x02 解决办法 控制台显示的时候缺省的是使用系统默认的字符集,比如windows下用的是GBk,但是默认情况下 ...

  6. Sublime + Python3 + 虚拟环境 + 去除 中文输出乱码

    MacBook Pro Retina 13 2013年底版 所用软件 1. Sublime Text 3安装 Virtualenv package 2. 用 iterm2 .或者终端安装zip:apt ...

  7. windows下解决PyCharm控制台中文输出乱码

    我用的PyCharm是2018.2版本 在调用os.system()的过程中遇到了控制台中文乱码的问题,具体如下 网上说的将两个Encoding格式都设置为UTF-8并没有解决问题,后来我将Proje ...

  8. python3中文输出乱码的问题

    最近使用you-get这个工具下载视频,发现命令行窗口里显示的媒体标题是乱码(但文件管理器里显示正常).我的命令行窗口的code page是936,sys.stdout.encoding是utf-8, ...

  9. Java控制台中输入中文输出乱码的解决办法

    Run---Run Configurations---Common---Encoding---Other---GBK Run Configurations里的Common中将编码方式改成GBK就正常了

  10. Jenkins控制台中文输出乱码解决方法

    1. 设置jenkins所在服务器环境变量,右键我的电脑→属性→高级系统设置→环境变量,添加JAVA_TOOL_OPTIONS 2.修改Tomcat配置,进入apache_tomcat/conf文件夹 ...

随机推荐

  1. 一文搞定WeakHashMap

    写在前面 在缓存场景下,由于内存是有限的,不能缓存所有对象,因此就需要一定的删除机制,淘汰掉一些对象.这个时候可能很快就想到了各种Cache数据过期策略,目前也有一些优秀的包提供了功能丰富的Cache ...

  2. 暑假集训CSP提高模拟18

    \[暑假集训CSP提高模拟 \ 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1 \] Very good problem, this make my news rotate. ...

  3. ChatGPT论文降重Prompt

    你是一个已经阅读过大量论文的论文写作专家.我正在设计一个基于xxx系统.接下来,我将给你一个论文段落,你可以使用调整句子用词.句子结构等方法,重新描述这段话,对文章的内容进行润色,使之更加接近论文的写 ...

  4. ARM64 SMP多核启动(下)- PSCI

    4.支持psci情况 上面说了pin-table的多核启动方式,看似很繁琐,实际上并不复杂,无外乎主处理器唤醒从处理器到指定地址上去执行指令,说他简单是相对于功能来说的,因为他只是实现了从处理器的启动 ...

  5. 一些OI常用小技巧啊

    1.卡常 \[---总有人以为自己比编译器聪明 \;\;\;by\;\;bezel \] 我们可能确实没有编译器聪明,但是,为了防止CCF的老人机出现什么问题,卡一卡常还是有必要的. 如果实在被逼无奈 ...

  6. OOP的核心思想

    1. 封装 既是信息封装,把一些信息进行封装成对象,只保留部分接口和方法与外部联系,能有效避免程序间相互依赖,实现代码模块间松藕合 : 2. 继承 子类自动继承父类的属性和方法,继承实现了代码的重用性 ...

  7. vuex 的modules 子模块总结

  8. GDOI绝望记——人生第一次省选普及

    时光匆匆,如白驹过隙. 转眼之间,我一在OI之路上走了2年半了.. 岁月不饶人,我却在不经意间饶了岁月. 自己到底是不是不如别人,这,是取决于自己的心态吧 Preface 人生中第一次去深圳(应该是吧 ...

  9. KubeSphere 在直播应用中的实践

    本文是上海站 Meetup 讲师唐明根据其分享内容整理的文章. 引言 目前媒体的主流传播渠道已从传统的报纸.广播.电视转向了互联网,各种视频及社交 App 成为了人们获取资讯的首选途径.苏州市广播电视 ...

  10. php运行redis测试

    在今天将官方的redis教程看完之后,想自己来一个测试. 按照官方给出的代码: 1 <?php 2 //连接本地的 Redis 服务 3 $redis = new Redis(); 4 $red ...