二 Java 编码那些事

建议先阅读:Java 编码那些事(一)
现在说说编码在Java中的实际运用 。在使用tomcat的时候 , 绝大部分同学都会遇到乱码的问题,查查文档,google一下解决方案啥的,都是设置这里,设置那里 , 或者在代码中添加编码方式,虽然最终问题解决了 , 但是你真的知道这是什么意思么?
在平时开发Java的时候,我们会遇到很多编码设置,其中包括:

  • Java文件的编码:Java文件的编码表示编写代码得时候,.java文件本身的编码,这个编码的影响在于将你的写的代码源文件复制一份,使用其他编辑器打开 , 若两个编辑器的默认编码方式不一样 , 则打开源文件就会变成乱码 。一般英文的影响不大,因为大多数编码都兼容ASCII编码,但是中文要是编码不正确,则会乱码 。
    IDEA的设置在:Setting->Editor->File Encodings中设置
  • JVM编码:JVM编码表示JVM在读取String类型的默认编码 , 可以使用Charset.defaultCharset().name() 获取 。可以在JVM启动参数中使用-Dfile.encoding=UTF-8进行设置 。
一般需要区分的就是这两种编码 。下面着重说下JVM编码的体现 。
字节流与字符流熟悉IO的同学应该都明白这两个流的区别 。一般会出现字符乱码都在于需要与其他程序进行IO的时候 。
先看看使用字节流进行读取文件的时候:
public static void main(String[] args){String path="G:\\test.txt";try(BufferedInputStream inputStream=new BufferedInputStream(new FileInputStream(path))) {for (byte bytes[] = new byte[1024]; inputStream.read(bytes) != -1; ) {String context = new String(bytes);System.out.println(context);}}catch (IOException e){e.printStackTrace();}}然后再G盘新建一个文本文件,输入一段文字 。使用默认的格式保存 。
可以查看输出:
??????????                                                                         乱码了,下面来分析一下:
首先这里是JVM运行时的编码,因此和JVM的编码设置有关 。打印JVM目前的编码设置:
System.out.println(Charset.defaultCharset().name());输出:UTF-8找到刚刚新建的文件test.txt,点击另存为,可以发现默认编码为ANSI,前一篇文章中说过,ANSI作为windows系统中的特殊存在,它在简体中文编码的情况下默认为GBK编码 。这便是乱码的原因,解决方案有两种:
  1. 设置JVM启动项:-Dfile.encoding = GB2312
  2. 在编码byte数组的时候,指定GB2312编码:String context = new String(bytes,"GB2312");
这里推荐第二种,毕竟UTF8更加通用
问题完美解决 。
同理,网络IO也能通过以上方法解决 。
看明白了上面的发现问题和解决问题的流程的同学,下次遇到文件编码的问题,相信应该能够独立解决问题 。
实战明白了各种编码问题,现在我们可以着手进行实战 。
第一次使用IDEA开发Servlet的时候,大多数都会遇见乱码问题 , 包括:
  • 控制台输出Tomcat日志乱码
  • 网页显示Servlet返回的中文乱码
虽然各种Google后 , 终于解决了 , 但是可能依然不明白其中的缘由 。下面我们来一探究竟
Tomcat日志首先解决Tomcat日志乱码的问题,首先要明白:Tomcat作为一个独立的进程,IDEA是怎么获取到Tomcat日志的呢?在IDEA控制台中的Tomcat启动日志中,我们可以找到一个日志记录:
 -Dcatalina.base=C:\xxx\.IntelliJIdea2018.3\system\tomcat\xxx复制选项中的路径,在文件夹中打开 , 进入logs文件夹,就可以发现这个是tomcat的日志文件输出路径,而IDEA正是读取了这个文件中的内容输出到控制台中,我们可以使用记事本打开日志文件,然后选择另存为 , 可以发现文件的默认编码是ANSI,也就说在简体中文下是GBK编码 。

推荐阅读