美文网首页
Java 中文乱码

Java 中文乱码

作者: _小毛驴 | 来源:发表于2021-01-20 11:23 被阅读0次

    运行环境:Windows 10 ;IDEA-2019.3;Tomcat 9.0.24;jdk 1.8.0_221;

    问题切入

    我在idea中开发ssm框架的项目,然后直接在集成的tomat中运行,其他日志都是正常显示,唯独mybatis的参数日志中文乱码。

    上面就是我遇到的具体乱码问题场景。从这个问题的出现,以及我解决的过程。让我有了写这篇文章的动机。
    中文乱码,是我们这些中文世界的程序员常见到想吐的问题。发生的频率如此频繁。解决的方式也是如此碰运气。让我也是很气馁。每一次遇到中文乱码,就像遇到一个新问题,你不知道是哪个环节出了问题,你也不知道需要怎样的配置解决。全靠百度搜索,碰运气解决。
    我思考了一通,尝试做个记录,尽量去发现解决的通用逻辑。
    解决乱码问题,我想要通过这么几步,首先,要明白编码/解码原理;其次,要知道所有环节的默认编码;最后,要知道解决问题的配置方式的含义。
    我也要按这个思路来梳理。

    乱码底层原理分析

    image.png

    画了个简单的图,如上面,正常情况下,解码和编码的过程中都要使用一致的编码格式。
    如果发生乱码,考虑存在以下问题:

    • 编码和解码的格式不一致。
    • 编码时使用的编码格式不支持字符,当时就乱码了。解码时,使用一致的编码格式,也会乱码。

    如果发生乱码,就要从上面的两种情况去考虑解决了。

    所有环节的默认编码

    这里,也是乱码问题最难解决的问题关键所在。因为,随着软件工业的发展,封装越来越厉害。终端使用者,根本不能知道终端使用之前,经历了多少个环节的编码和解码过程。所以,你去解决乱码问题,也只能是丈二和尚摸不着头脑了。
    我这里也只能慢慢的穷举我知道的环节的默认编码。

    • windows系统默认编码 : GBK
      这也是很多乱码的源泉。程序员都在说要推进统一编码格式UTF-8。可是系统级别也没有使用UTF-8呀。
    • Java文件编译后形成class默认编码:UTF-16编码
    • JVM中的默认编码:受平台,配置影响。
    • idea开发工具默认编码:idea本质也是一个java应用,还是遵循JVM的编码设置规则。
    • tomcat服务器默认编码:tomcat本质也是一个java的应用,还是遵循JVM的编码设置规则。
    • 源码文件默认编码:根据自己设定。

    配置参数含义

    • -Dfile.encoding=UTF-8

    -Dfile.encoding 解释:
    在命令行中输入 java,在给出的提示中会出现 -D 的说明:
    -D<name>=<value> # set a system property
    -D 后面需要跟一个键值对,作用是设置一项系统属性
    对 -Dfile.encoding=UTF-8 来说就是设置系统属性 file.encoding 为 UTF-8
    那么 file.encoding 什么意思?字面意思为文件编码。
    搜索 java 源码,只能找到 4 个文件中包含 file.encoding 的文件,
    也就是说,只有四个文件调用了 file.encoding 这个属性。
    在 java.nio.charset 包中的 Charset.java 中,这段话的意思说的很明确了。
    简单说就是默认字符集是在 java 虚拟机启动时决定的,
    依赖于 java 虚拟机所在的操作系统的区域以及字符集。
    代码中可以看到,默认字符集就是从 file.encoding 这个属性中获取的。

    • idea集成tomcat后,tomcat的编码设置


      image.png
    • idea工具的编码设置


      image.png

    总结

    我力图去理解乱码的问题解决,我后续还会继续充实此文。或者,随着我对编码的理解加深,也会推翻现在的逻辑。

    附录:
    有些段落引用自:http://yang3wei.github.io/blog/2013/02/10/java-dfile-dot-encoding-equals-utf-8-gan-diao-luan-ma/

    相关文章

      网友评论

          本文标题:Java 中文乱码

          本文链接:https://www.haomeiwen.com/subject/tgrrzktx.html