JAVA中文编码问题
先介绍一个概念:本地编码,所谓本地编码是操作系统采用的中文编码格式,一般是“GBK”或“GB2312”,可以用System.getProperty("file.encoding")。
本文从以下几个方面来对JAVA中的中文编码进行说明。
1.中文存储方式
2.编码变换问题
3.解决方法
第一:中文存储方式
本部分分控制台应用,WEB应用来分析:
对控制台应用:
JAVA文件--->CLASS文件---->虚拟机- - - >控制台输出
本地编码 UTF-8 UTF-8 本地编码
编辑源文件并保存,中文以本地编码方式保存, 利用javac编译后中文以UTF-8方式存在与类文件中,程序运行时,中文也是以UTF-8的格式存在,进行相关处理后,在控制台输出时,再从UTF-8转换为本地编码显示在控制台上.
对WEB应用:
JSP文件--->临时Servlet文件--->Servlet类文件--->虚拟机
本地编码 本地编码(缺省) UTF-8 UTF-8
WEB应用中客户端与服务器数据交互:
客户端---->传递---->服务器---->传递---->GBK
GBK ISO-8859-1 GBK ISO-8859-1 GBK
用户在表单中输入汉字时,编码格式肯定是本地编码,在发送之前IE把中文转换成ISO-8859-1,再发送到服务器,服务器接收到ISO-8859-1格式码流后,再变换成本地编码,服务器进行处理后,如果返回到客户端的是中文,也需要先变换成ISO-8859-1,然后再传递到客户端,客户端再用本地编码进行解释并显示。
数据库应用:
JAVA文件--->CLASS文件---->虚拟机- - - >传递
本地编码 UTF-8 UTF-8 本地编码
缺省在程序与数据库之间传递数据是以ISO-8859-1方式,JDBC首先把UNICODE格式的串转化为ISO-8859-1,然后传递到数据库,数据库进行处理后,把GBK编码的中文首先编码成ISO-8859-1再返回到客户端。
第二:编码变换问题
中文(不管是GBK还是GB2312),英文(ISO-8859-1),UTF-8三种不同的字符集之间存在映射表,通过映射表可以实现彼此之间的转换。可以实现中文<->英文、中文->UTF-8、英文UTF-8之间的变换,中英文到UTF-8的转换主要是虚拟机实现的。变换的过程就是编码和解码的过程,比如从中文”世界“转换成UTF-8格式,”世界“的中文编码为0xCAC0BDE7,在类文件和虚拟机中的编码为0xE4B898E7958C,在中文与UTF-8的映射表中肯定存在这么一项,如果在程序中有如下代码:
1. String str = "世界";//在虚拟机中的形式为0xE4B898E7958C
2. byte[] buf = str.getBytes("GBK");//编码,从UTF-8为GBK,buf中存放的肯定是0xCAC0BDE7
3. System.out.println(str); //控制台输出
4. System.out.println(new String(buf)); //解码为中文”世界“并显示
5. buf = str.getBytes("ISO-8859-1"); //编码,从UTF-8到ISO-8859-1,此时出现问题
6. System.out.println(new String(buf)); //解码为中文,显示 ??,说明出现了编码错误
7. System.out.println(new String(buf, "ISO-8859-1")); //编码为ISO-8859-1,显示 ??,说明出现编码错误
第5行代码出现问题,因为目前内存中的UNICODE 0xE4B898E7958C是从GBK的0xCAC0BDE7转换过来的,如果编码成ISO-8859-1,在UTF-8<->ISO-8859-1的映射表中根本不存在该表目,所以在该行开始出现编码错误。如果显示的是??肯定是编码错误,如果是乱码,往往是显示问题。此时,无论如何也不能由buf中的数据再变换到正确的编码。
第三:解决方法
解决中文编码问题的大原则就是:编解码必须保持一致。
比如程序中第2行就是从UTF-8编码到中文(GBK),跟前面的从中文(GBK)解码为UTF-8保持一致。也就是先从0xCAC0BDE7到0xE4B898E7958C,然后在第2行,再由0xE4B898E7958C到0xCAC0BDE7,此时控制台可以正确显示中文。即便没有第2行代码,那么在控制台显示前,控制台会先完成虚拟机中的0xE4B898E7958C到0xCAC0BDE7的转换,再进行显示。
在WEB开发中,为避免中文问题,可考虑采用如下方法:
在Servlet的doGet和doPost方法中:
request.setCharacterEncoding("GB2312"); //设置输入编码格式
response.setContentType("text/html;charset=GB2312");//设置输出编码格式
在JSP中:
<%@page contentType="text/html;charset=GBK"%>
<%request.setCharacterEncoding("GBK");%>
在数据库编程时,要首先保证数据库使用的是中文编码、另外再需要时设置数据库连接的编码格式为中文。
只要你全面掌握了中文的源文件、类文件、虚拟机和传输过程中的编码格式,并牢记编解码一致的原则,相信你能解决所有的中文问题。
网友:忽略了java文件自身也是可以指定编码方式
网友:源文件的编码格式不能指定,只能用操作系统缺省的编码格式.当然在编译的时候可以用-encoding选项来指定类文件的中文编码格式.
分享到:
相关推荐
深入剖析Java 编程中的中文问题及建议最优解决方法,中文乱码问题是必须解决的~!
深入剖析Java编程中的中文问题及建议最优解决方法.pdf
面试经验
深入剖析Java编程中的中文问题及建议最优解决方法
对Java序列化的深入了解不仅可以展示你的编程技能,还能体现出你对Java核心概念的掌握。本文精选了20道复杂的Java序列化面试题,并提供了详细的解析,旨在帮助你更好地理解Java序列化的原理、应用和相关问题。通过...
如题,关于Java中中文乱码的形成原因和解决方法做了一个比较深入的剖析以及建议最佳解决方案。
主要介绍了深入剖析Java编程中的序列化,文中谈到了序列化时对象的继承等各种问题,案例详尽,强烈推荐!需要的朋友可以参考下
详细介绍java 编程中的细节编程规范,涉及代码组织风格,注释,命名,声明,内存管理,异常处理等.
此外,本书的配套光盘还免费提供了价值人民币330元的java教学视频,对java语言进行了全面讲解,帮助一些不会java语言的读者快速地从java基础知识的学习中过渡到java web的学习与开发上. 第1部分 xml篇. 第1章 xml...
此外,本书的配套光盘还免费提供了价值人民币330元的java教学视频,对java语言进行了全面讲解,帮助一些不会java语言的读者快速地从java基础知识的学习中过渡到java web的学习与开发上. 第1部分 xml篇. 第1章 xml...
此外,本书的配套光盘还免费提供了价值人民币330元的java教学视频,对java语言进行了全面讲解,帮助一些不会java语言的读者快速地从java基础知识的学习中过渡到java web的学习与开发上. 第1部分 xml篇. 第1章 xml...
鑫编写的《Java Web开发详解——XML+DTD+XML Schema+XSLT+Servlet3.0+JSP2.2深入剖析与实例应用》共分4篇,从XML、XML Schema、XSLT、Servlet、JSP和应用的角度向读者展示了Java Web开发中各种技术的应用,循序渐进...
《Java程序性能优化:让你的Java程序更快、更稳定》以Java性能调优为主线,系统地阐述了与Java性能优化相关...专 注于Java应用程序的优化方法、技巧和思想,深入剖析软件设计层面、代码层面、JVM虚拟机层面的优化方法。
此外,本书的配套光盘还免费提供了价值人民币330元的java教学视频,对java语言进行了全面讲解,帮助一些不会java语言的读者快速地从java基础知识的学习中过渡到java web的学习与开发上. 第1部分 xml篇. 第1章 xml...
第6章介绍了Java中的大部分并发容器,并深入剖析其实现原理,让读者领略大师的设计技巧。 第7章介绍了Java中的原子操作类,并给出一些实例。 第8章介绍了Java中提供的并发工具类,这是并发编程中的瑞士军刀。 第9章...
Abstract:本文深入分析了Java程序设计中Java编译器对Java源文件和JVM对class类文件的编码/解码过程,通过此过程的解析透视出了Java编程中中文问题产生的根本原因,最后给出了建议的最优化的解决Java中文问题的方法...
李若亮老师带你深入剖析Java编程中所内存涉及的方方面面,从JVM的内存申请,到Java语言的内存加载以及Java语言的内存回收,方方面面面,逐一剖析,体会Java语言的独特魅力。正如范大师所说:你不仅要知道它是怎么来...
它选取了Java并发编程中最核心的技术进行讲解,从JDK源码、JVM、CPU等多角度全面剖析和讲解了Java并发编程的框架、工具、原理和方法,对Java并发编程进行了最为深入和透彻的阐述。 《Java并发编程的艺术》内容涵盖...