`
yyyyy5101
  • 浏览: 151538 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

关于乱码问题

阅读更多
1 乱码的根源
在计算机中所有的数据最终都必须序列化成字节序列,如果数据恰好表示就是字符,这种序列化的过程称作编码 , 反之当要读取序列化的数据,要先反序列化,对字符数据这种过程称之为解码 。 编码和解码过程有着紧密的关联,都由编码 (前述的’编码’是一个动词,这里是一个名词)决定, 一个编码(如UTF-8,GBK)就决定了一个编码过程和一个解码过程。 只有当编码过程和解码过程使用相同的编码时,字符数据才能被正确解释,否则乱码就产生了。 乱码问题的根源就在于对字符数据的编码(写入)和解码(读取)使用了不同的编码 。



为了便于说明,我们称字符数据第一次被序列化(写入或编码)时使用的编码称为初始编码 , 最后一次被序列化时使用的编码称为当前编码 。 要反序列化(读取或解码)字符数据一般来说要使用和初始编码相同的编码。 以文本文件为例,初始编码为GBK的文本文件一般只能使用GBK来解码才能读到正确的内容, 否则就会得到乱码(不正确或毫无意义的内容)。 但是也有例外,初始编码为GB2312的文本文件能够使用GBK编码来读取,这是因为GBK兼容GB2312, 类似的,初始编码为ISO-8859-1的文本文件可以使用UTF-8编码来读取,反之却不行,初始编码 为UTF-8的文本文件不能使用ISO-8859-1来读取。假设一个初始编码为GB2312的文本文件用UTF-8 编码读取,然后再使用UTF-8编码写入到同一个文件, 下次读取时无论使用GB2312编码还是使用UTF-8编码都无法回复到以前的内容。 使用与初始编码不兼容的编码先读取然后写入一般会导致初始内容遭到永久性破坏从而表现出乱码 。 这里的例外是ISO-8859-1,它是个特殊的编码,恰好有256(一个字节能够容纳的数)个字符。 对任意初始编码的文本文件,使用ISO-8859-1读取它的内容(虽然读取的内容可能表现出乱码), 然后再以ISO-8859-1写入原文件,文件内容保持不变,下次仍能以初始编码来读取文件的正确内容。 这或许是为什么JSP的许多默认编码设置成ISO-8859-1的原因。



这种乱码出现在需要多次序列化和反序列的情况下,而这在Java程序中非常常见。 为了避免乱码需要确保所有的序列化和反序列化过程使用相同的编码 ,任何一个过程 使用了不正确的编码都将导致乱码,这使得乱码问题变得十分复杂,这首先要求 我们必须对程序所有的编码和解码过程都十分清楚。下面我们就要探讨常见Java程序的编码和解码过程。

2 编码和解码过程
2.1 Java独立应用程序
在考虑Java应用程序的编码和解码过程时不仅仅要考虑运行时编码和解码过程,而且要考虑编译时的编码和 解码过程。通常Java独立应用程序的第一个编码过程是将Java程序写入到一个后缀为”.java”的文本文件中, 在编译java程序时,编译器需要知道Java文件的编码,其默认使用系统平台的编码,Windows一般是“GBK” ,Linux一般是“UTF-8”,可以使用-encoding选项来指定java文件的编码。 如果编译器使用的编码和Java文件使用的编码不相同,就会造成乱码问题。 单个人使用单个平台开发时一般不会遇到这种问题,多人开发时必须统一Java源文件的编码, 我一般喜欢使用UTF-8,编译时也要指定编码,即使源文件编码与平台默认编码相同也是如此, 这样才不会依赖某个平台。使用不同的方式来编译Java程序时,它们都有自己的方式来指定 源文件的编码,javac通过”-encoding”选项,ant通过javac任务的encoding属性,maven 通过设置compiler插件的encoding元素值。值得注意的是,当指定了错误的编码时,编译 可能都会通不过。



运行时的编码和解码过程主要是对文本文件的读和写。在Java中通过下面的方式的获得一个Writer(字符写入器):

Writer writer = new  OutputStreamWriter(new  FileOutputStream("your_file_name" ), "replace_it_with_encoding" );


当不指定文件编码时,默认编码是系统属性file.encoding的值,可以在java启动时通过”-Dfile.encoding=utf-8”来设置默认 编码为utf-8。最好在创建Writer时指定文件编码,这可以避免对平台的依赖。 通过下面的方式获得一个Reader(字符读取器):

Reader reader = new  InputStreamReader(new  FileInputStream("your_file_name" ), "replace_it_with_encoding" );


同样不指定编码时,默认编码是系统属性file.encoding的值,创建Reader时最好显式指定编码值,这样可以避免对平台的依赖。 对于配置文件(如xml文件)我的建议是统一使用“UTF-8”编码。 一般来说这种乱码问题很容易解决,只需要指定和文件对应的编码就可以了。 一个例外是properties文件的读取,在jdk6之前,没有对属性文件指定编码的API, Properties只有一个load(InputStream)方法,jdk6中增加一个load(Reader)方法, 这样就可以对属性文件指定编码。jdk6之前properties文件的编码必须是ISO-8859-1, 不能表示的字符只能使用Unicode转义符来表示,需要使用native2ascii工具将某种编码 的属性文件转换成属性文件所需的格式。



另一个比较常见的运行时的编码和解码过程是对数据库的读和写。这和文件的读写类似,只不过Java没有提供公开 的API来设置数据库的编码,这一般由驱动器自动检测,在MySQL中可以通过连接参数来设置数据库的编码。

2.2 Java Web应用程序
Java独立应用程序中的编码和解码过程对于Java Web应用程序也是适用的,这里只探讨和Java Web应用程序相关的 编码和解码过程。同对Java源文件的编译一样,我们先要讨论JSP的编译。对JSP的编译一般分为两步,首先要将 JSP文件转换成Java文件,然后再编译这个Java文件得到class文件,因此这有两个编码和解码过程,但是这个过程是 透明的(读取JSP文件和Java文件使用的编码是相同的),我们可以认为JSP编译器直接将JSP文件编译成class文件。 同样我们必须保证JSP编译器读取JSP文件使用的编码是这个JSP文件的初始编码。和Java编译器不同,JSP编译器 使用的编码是在JSP文件中指定的,例如要使JSP编译器使用UTF-8的编码来读取JSP文件,可以使用:

<%@ page  pageEncoding= "utf-8" %>


如果不指定页面编码,默认值为ISO-8859-1,由于上面所说的ISO-8859-1编码的特殊性,只要正确设置响应编码, 一般来说不会观察到乱码。但是在某些特殊情况下,它可能导致原本正确的JSP文件无法编译,更重要的是编译成 Java文件可能是乱码,我们可能有时需要查看这些Java文件,这会造成稍许不便,因而最好还是设置正确的JSP页面 编码。



当响应是字符数据时,这里假设是HTML内容,需要使用某种编码将它序列化成字节序列,浏览器 (或者其它的客户端)读取响应时必须使用相同的编码,否则页面可能就会显示乱码, 一般浏览器会根据响应头Content-Type的值自动检测响应的编码。为了使浏览器能够检测到 正确的编码,可以在JSP中通过如下方式设置Content-Type响应头:

<%@ page   contentType = "text/html;charset=utf-8" %>


上面的代码设置响应头Content-Type的值为“text/html;charset=utf-8”,浏览器会自动使用 UTF-8编码来读取响应内容。如果浏览器自动决定的编码不正确(这是由于没有设置正确的Content-Type响应头), 主流浏览器(如IE和Firefox)都允许手动选择编码。如果在JSP中没有指定ContentType,则会根据 pageEncoding的值来设置响应编码,如果pageEncoding也没有设置,那么响应编码的值就是ISO-8859-1。 另外响应的编码的值可以在运行时调用方法response.setCharacterEncoding(“your_encoding”)来动态改变。



和响应编码对应的是请求编码。请求一般是由浏览器发送的,Firefox和IE中使用的编码是当前页面的编码, Firefox和IE中都可以通过菜单”查看→字符编码”得到当前页面的编码,它通常就是响应编码(如果没有手工设置编码)。 为了读取到正确的内容,服务器端也必须使用同样的编码(通常是响应编码)来读取请求内容。在JSP中无法直接设置请求编码, 但是可以通过request.setCharacterEncoding(“your_encoding”)来设置。不幸的是,在Tomcat中并没有使用请求编码来解码URI, 默认使用ISO-8859-1编码,要修改URI的编码需要在tomcat的配置文件中设置。

分享到:
评论

相关推荐

    关于乱码问题简单分析

    ### 关于JSP乱码问题的深入解析 #### 一、引言 在Web开发过程中,尤其是使用Java Server Pages(JSP)进行页面渲染时,字符编码问题常常导致页面显示出现乱码。本文将对JSP中的乱码问题进行详细的分析,并提供一...

    ffmpeg.exe在windows修正乱码,命令行支持中文字幕文件名

    首先,关于乱码问题,这通常是因为FFmpeg在Windows上默认不支持Unicode编码,尤其是在命令行环境下,可能会对非ASCII字符(如中文字符)处理不当。为了解决这个问题,开发者可能对FFmpeg进行了编译配置修改,使其...

    Java关于中文乱码问题的多种解决方法

    在Java编程中,中文乱码问题是一个常见的困扰,尤其是在处理文件读写、网络传输或数据库操作时。本文将深入探讨几种解决Java中中文乱码问题的方法,并以MyEclipse为开发环境,结合实际示例进行讲解。 1. 文件读写中...

    关于GBK和Unicode字符集转换乱码问题

    ### 关于GBK和Unicode字符集转换乱码问题 在计算机科学与互联网技术中,字符集是一种用于表示文本的标准集合,不同的字符集适用于不同的语言环境。本文将深入探讨GBK与Unicode这两种字符集之间的转换问题,特别是在...

    struts-hibernate-sprint开发详解 乱码问题 连接池

    关于乱码问题,通常需要在Servlet容器(如Tomcat)和应用程序中设置正确的字符编码。例如,在HTTP响应头中设置`Content-Type`为`text/html;charset=UTF-8`,并在JSP页面中使用`;charset=UTF-8"%&gt;`。此外,确保数据库...

    关于处理中文乱码问题 Filter 代码

    本文将重点解析“关于处理中文乱码问题 Filter 代码”的相关知识点,并结合Java Servlet API进行详细讲解。 首先,我们要理解什么是Filter(过滤器)。在Java Web开发中,Filter是Servlet API的一部分,它允许我们...

    Struts的乱码问题

    ### Struts框架中的乱码问题解析与解决方案 #### 背景介绍 在Web开发过程中,尤其是使用Java Web框架如Struts进行项目开发时,经常遇到的一个问题是中文字符的乱码问题。这个问题主要体现在中文字符在Web页面上的...

    关于MathType6中文乱码问题的解决方案.docx

    mathtype中文乱码问题的解决

    关于Dreamweaver乱码问题的解决方案

    在使用Adobe Dreamweaver进行网页编辑时,可能会遇到乱码问题,这主要归因于两个主要原因。首先,可能是由于在创建网页时没有明确指定使用的字符编码,这导致Dreamweaver无法正确识别和显示文本。其次,如果你安装了...

    关于处理Javaweb中中文乱码的问题文.pdf

    Java Web 技术开发中文乱码问题解决方案 本文档是基于 Java Web 技术开发中文乱码问题的深入探讨,旨在解决 Java Web 开发中中文乱码问题的根本办法。文章首先详细分析中文乱码问题产生的原因,然后提出合理的解决...

    关于Mysql、Php、phpMyAdmin、Zend 乱码的问题?

    乱码问题解决方案 关于Mysql、Php、phpMyAdmin、Zend 乱码的问题是一个常见的问题,而解决它们并不困难。只要我们了解Mysql和浏览器显示的原理,就可以轻松地避免乱码的困扰。 系统说明 在解决乱码问题之前,我们...

    关于asp.net中中文产生乱码问题

    ### ASP.NET 中中文乱码问题解析 #### 一、背景介绍 在开发基于 ASP.NET 的应用程序时,中文字符的正确显示往往是一个不容忽视的问题。由于编码格式的不同或配置不正确,很容易导致页面上的中文出现乱码现象。本文...

    jsp乱码解决方案 本方案解决了jsp常见的乱码问题

    本文将详细介绍如何有效地解决JSP中的乱码问题,并通过具体的代码示例来展示解决方案。 #### 二、乱码产生的原因 在深入探讨解决方案之前,首先需要了解乱码产生的原因。通常来说,乱码是由于客户端和服务器端之间...

    解决HttpClient中文乱码问题jar文件

    然而,当处理包含中文字符的请求或响应时,如果没有正确配置,就可能会出现乱码问题。这个问题通常涉及到字符编码设置,包括请求头、请求体以及响应的解析。 HttpClient中文乱码问题的核心在于字符编码不一致或者未...

    关于Qt中translate、tr关系以及中文乱码的问题

    Qt 中 translate、tr 关系以及中文乱码的问题 在 Qt 应用程序中,translate 和 tr 是两个常用的国际化方法,但是它们之间的关系和中文乱码的问题却经常引起混淆。在本文中,我们将详细讨论 translate 和 tr 的关系...

    jsp关于解决中文乱码的问题

    本文将详细探讨如何在JSP环境中解决中文乱码问题,并提供具体的实现方法。 #### 一、乱码原因分析 在了解解决方案之前,首先需要明确导致中文乱码的原因: 1. **编码不一致**:客户端与服务器端使用的字符集不一致...

    解决Labview中关于读取txt文本文件,读出来是乱码的问题

    解决Labview中关于读取txt文本文件,读出来是乱码的问题

    Windows10 + qt5.8.0解决编码乱码问题总结.pdf

    其次,关于代码中的中文乱码问题,需要对.cpp文件的编码方式进行检查。具体操作为选中.cpp文件后,选择编辑-&gt;Select Encoding,并从中选择相应的编码方式,最后点击“按编码保存”以确保文件被正确编码保存。 对于...

    解决Inno Setup制作中文安装包在非中文系统上显示乱码的问题

    在解决了乱码的问题后,我们还需要设置区域中关于 Language for non-Unicode programs 的设置,将 Current language for non-Unicode programs 设置成中文,以便在非中文系统上正确地显示中文字符。 解决 Inno ...

Global site tag (gtag.js) - Google Analytics