`
JAVA天地
  • 浏览: 673686 次
  • 性别: Icon_minigender_1
  • 来自: 太原
文章分类
社区版块
存档分类
最新评论

中文编码问题全面分析

阅读更多


  基于web的应用开发都会涉及到编码问题,特别是中文编码,一直是开发人员常见问题之一,也最为初学者所困扰。我们知道计算机最初是按英语单字节字符设计的,现在很多软件及系统仍然默认使用ISO8859-1编码来表示。因此,有的时候处理中文字符就会出现乱码的现象。出现乱码不只是简单的由某个软件所造成的,很可能与系统或相关软件有关联影响。

  在web软件开发过程中,我们将涉及到四个可能会导致字符编码问题的方面,分别为浏览器、中间件(WEB服务器)、数据库、操作系统。在这四个方面,都有影响字符编码的因素存在。每个方面都有自己默认支持的字符编码,如果这四方面的编码是统一的一种字符集,一定不会出现乱码问题。出问了乱码,一定是其中某部分有不同的字符集编码存在。目前解决此类的问题的方法也是多种多样,本文提到的也是其中的一种,也许别人有更好的方法欢迎大家一起进行探讨。
  操作系统本地编码与你所选择安装的系统版本有关,如果你是简体windows,就是GB编码,如果你是繁体windows,就是BIG5编码。所以我们在不同的操作系统上创建一个源码文件,由于系统的不同就会存储成不同编码格式。这个时候当采用另外一种编码格式的操作系统来读取这个源码文件的时候,内容就会是乱码的。同理,采用浏览器解析的时候也是一样的。如:你的源码文件是在BIG5编码的操作系统下创建的,而浏览器或是WEB服务器(apache等)采用的是GB2312编码的,这个时候所显示的内容也一定是乱码的。知道乱码的原因了,我们就可以有效的解决这个问题。
  要想彻底解决这个问题,就需要我们决定采用统一的编码。对于当前众多的字符集编码,是UNICODE、ISO8859_1 、GBK还是UTF-8。
  UNICODE编码不兼容ISO8859-1编码,而且容易占用更多的空间。因为对于英文字母,UNICODE也需要两个字节来表示,不便于传输和存储。而UTF-8编码兼容ISO8859-1编码,同时也可以用来表示所有语言的字符。UTF-8编码是不定长编码,每一个字符的长度从1-6个字节不等,并且自带简单的校验功能。在UTF-8编码中通常英文字母都是用一个字节表示,而汉字使用三个字节。虽然说UTF-8编码可以使用更少的空间,但只是相对于UNICODE编码来言,如果只是处理汉字,使用GB2312/GBK才是最节省的。WEB应用,网页中会包含大量的英文字符,由于UTF-8编码对ISO8859-1编码兼容,它是一种兼容所有语言的编码方式 ,所以建议采用UTF-8编码为最佳选择。如果决定采用UTF-8编码,做为统一编码。从开发环境到数据库、中间件、系统平台都需要进行统一。
  开发基于WEB的应用,应该了解到所采用的开发语言内部运算中,对字符操作的编码过程。如java语言,在内部将涉及到的所有字符串都会被转化为UTF-8编码来进行运算。
  字符串在被开发语言转化之前,字符串的字符集是什么? 很多开发语言总是根据操作系统的默认编码字符集来决定字符串的初始编码,而且编译或解释系统的输入和输出的都是采取操作系统的默认编码。问题往往就出在输入与输出的地方。而输入与输出部分涉及到WEB服务器、浏览器、数据库等。出现乱码的时候要分析清楚乱码出自哪儿个部分,是输入部分,还是输出部分,确定问题很是困难。下面分别从几个部分来说这个问题。
  
一,开发环境及浏览器部分
  将开发环境的默认字符集设置为UTF-8编码,很多开发工具都可以自定义设置,如Eclipse可以设置全局默认字符集编码也可以在项目属性中设置项目自身采用的字符集编码。
这样在创建源码文件的时候,文件本身就会采用UTF-8编码格式进行存储。
  在WEB开发过程中,各类源代码文件都是文本文件格式的。如最常见的HTML文件,它就是以文本文件格式存储的。这些文件如果是在系统内直接建立的文件,它的编码就是系统的默认编码。如果是在开发工具中创建的文件,一般情况上都是由开发工具的默认编码设置来决定的。而在HTML文件里,还要使用HTML语法,指定了该文件内容所使用的编码(如< meta http-equiv="content-type" content="text/html; charset=UTF-8">)。如果HTML文件内容没有指定编码,则浏览器自动识别文件的编码。如果HTML内容指定了编码,则浏览器使用HTML指定的编码来显示内容。通常情况下,HTML文件指定的charset和HTML文件自身的编码是一致的,但也有不一致的情况,如果不一致,就会导致网页乱码(此处乱码,只和文本文件编码有关,和数据库无关。)使用专门的网页编辑工具(比如Dreamwave),会自动根据网页中的charset值来编码文件。
二,程序文件部分
  页面文件主要包括html文件及脚本文件及其它由开发语言直接输出内容的文件。对于html文件的编码问题,前面讲过了,这里不再重复。开发语言输出的文件,有的是需要进行编码设置的,如jsp开发的时候,需要在jsp文件的头部对字符集进行声明。
如:<%@ page contentType="text/html;charset= utf-8" %>
在Jsp的html代码中,声明UTF-8编码:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
这样只要保证了这个页面内容的编码与文件本身编码一至就会避免与文件相关的乱码。再有乱码就可能是数据在传递过程中编码不同导致的。对于数据传递过程中出现乱码,一般采用对数据时行过滤来处理,数据统一经过某个程序进行编码处理来解决这个问题。
  例如在java的web应用中采用过滤器的方式进行编码处理,将所有来自浏览器的请求(request)转换为UTF-8,因为浏览器发过来的请求包根据浏览器所在的操作系统编码,可能是各种形式编码。网上这方面的源代码很多,下面就是编码过滤器的源代码。需要配置web.xml 激活该Filter。

SetCharacterEncodingFilter源文件

packageorg.kyle.web.sample;
importjava.io.IOException;
importjavax.servlet.Filter;
importjavax.servlet.FilterChain;
importjavax.servlet.FilterConfig;
importjavax.servlet.ServletException;
importjavax.servlet.ServletRequest;
importjavax.servlet.ServletResponse;
importjavax.servlet.UnavailableException;
publicclassSetCharacterEncodingFilterimplementsFilter
...{
/***//**
*Thedefaultcharacterencodingtosetforrequeststhatpassthrough
*thisfilter.
*/

protectedStringencoding=null;

/***//**
*Thefilterconfigurationobjectweareassociatedwith.Ifthisvalue
*isnull,thisfilterinstanceisnotcurrentlyconfigured.
*/

protectedFilterConfigfilterConfig=null;


/***//**
*Shouldacharacterencodingspecifiedbytheclientbeignored?
*/

protectedbooleanignore=true;

/***//**
*Takethisfilteroutofservice.
*/

publicvoiddestroy()
...{
this.encoding=null;
this.filterConfig=null;
}


/***//**
*Selectandset(ifspecified)thecharacterencodingtobeusedto
*interpretrequestparametersforthisrequest.
*
*
@paramrequestTheservletrequestweareprocessing
*
@paramresultTheservletresponsewearecreating
*
@paramchainThefilterchainweareprocessing
*
*
@exceptionIOExceptionifaninput/outputerroroccurs
*
@exceptionServletExceptionifaservleterroroccurs
*/

publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,
FilterChainchain)
throwsIOException,ServletException
...{

//Conditionallyselectandsetthecharacterencodingtobeused
if(ignore||(request.getCharacterEncoding()==null))
...{
Stringencoding
=selectEncoding(request);
if(encoding!=null)
request.setCharacterEncoding(encoding);
}


//Passcontrolontothenextfilter
chain.doFilter(request,response);
}



/***//**
*Placethisfilterintoservice.
*
*
@paramfilterConfigThefilterconfigurationobject
*
*encoding
*UTF-8
*
*/

publicvoidinit(FilterConfigfilterConfig)throwsServletException
...{
this.filterConfig=filterConfig;
this.encoding=filterConfig.getInitParameter("encoding");
Stringvalue
=filterConfig.getInitParameter("ignore");
if(value==null)
this.ignore=true;
elseif(value.equalsIgnoreCase("true"))
this.ignore=true;
elseif(value.equalsIgnoreCase("yes"))
this.ignore=true;
else
this.ignore=false;
}


/***//**
*Selectanappropriatecharacterencodingtobeused,basedonthe
*characteristicsofthecurrentrequestand/orfilterinitialization
*parameters.Ifnocharacterencodingshouldbeset,return
*null.
*


*Thedefaultimplementationunconditionallyreturnsthevalueconfigured
*bytheencodinginitializationparameterforthis
*filter.
*
*
@paramrequestTheservletrequestweareprocessing
*/

protectedStringselectEncoding(ServletRequestrequest)
...{
return(this.encoding);
}

}



*Thedefaultimplementationunconditionallyreturnsthevalueconfigured
*bytheencodinginitializationparameterforthis
*filter.
*
*@paramrequestTheservletrequestweareprocessing
*/
protectedStringselectEncoding(ServletRequestrequest)
...{
return(this.encoding);
}

}
在web.xml文件中加注册这个过滤器

<filter>
<filter-name>setCharacterEncodingFilter</filter-name>
<display-name>setCharacterEncodingFilter</display-name>
<description>setCharacterEncodingFilter</description>
<filter-class>org.kyle.web.sample.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
这样就可以避免数据在传递过程中因编码不同造成乱码问题。
三,中间件(WEB服务器)
设置WEB服务器的默认编码为UTF-8,与文件编码及文件内容声明编码相同,这样保证了WEB服务器在解释文件的时候不出现乱码问题。
如:
Apache服务器可以在它的httpd.conf配置文件中增加AddDefaultCharset utf-8设置。
Weblogic服务器可以在WEB-INF下的web.xml文件中加入以下设置就可以解决这个问题。

<context-param>
<param-name>weblogic.httpd.inputCharset./*</param-name>
<param-value>utf-8</param-value>
</context-param>
其它的WEB服务器在其配置文件中都提供设置默认编码的选项,这里不再一一列举。

四,数据库
  经过上面的处理,会发现你的web程序运转起来后,程序已没有了乱码问题。但是在增加记录的时候有的时候也有乱码出现。这是因为你的数据库编码与你通过程序输入的数据编码不同导致的。这需要设置数据库的编码。每种数据库都有直接修改数据库默认编码的配置项。如mysql数据库,可以在它的my.cnf(win:my.ini|unix/linux:my.cnf)配置文件中设置:
[mysql]
default-character-set=utf-8
但是不建议直接修改数据库的这个编码设置。如果修改了数据库的默认编码配置,就破坏了数据库原有的环境,而数据库通常情况下是多人在使用,并不是做为唯一的项目应用。
在我们的程序里可以采用在连接数据库的时候指定编码来解决这个问题。
通过java程序操作数据库的时候,连接数据库的URL可以写成:
useUnicode=true;characterEncoding=utf-8
如连接mysql数据库:
jdbc:mysql://localhost/test?useUnicode=true;characterEncoding=utf-8
通过PHP程序操作数据库的时候,可以先执行mysql_query(“set names xxxx”);其中xxxx是你网页的编码(charset=xxxx),如果网页中charset=utf8,则xxxx=utf8,如果网页中 charset=gb2312,则xxxx=gb2312。
  通过上面几部分的处理,我们可以彻底解决操作系统、开发环境、web服务器、数据库四部分在整个WEB应用中产生乱码的问题。当然很多时候我们没办法将这四部分调整为相同的编码。如你采用的是别人的web服务器,没有权力修改web服务器的默认编码,那么只有在你的程序中对于需要编码的地方进行转换处理,转换成web服务器相同的编码即可。
分享到:
评论

相关推荐

    深入分析Java中的中文编码问题

    ### 深入分析Java中的中文编码问题 #### 一、引言 在软件开发过程中,尤其是涉及到...通过对编码格式的理解、常见问题的分析以及合理的解决方案,可以有效地减少甚至避免中文乱码的问题,提高应用的质量和用户体验。

    JSPServlet 中的汉字编码问题

    #### 四、JSP 和 Servlet 中汉字编码问题分析 在JSP和Servlet开发中,最常见的汉字编码问题是页面显示乱码。这通常是由于服务器端和客户端使用的编码格式不一致所导致的。 - **JSP 页面中的编码问题**: - 在JSP...

    java中文乱码问题

    在Java编程中,中文乱码问题是一个常见的困扰,...通过以上分析,我们对Java中的中文乱码问题有了全面的理解。在遇到此类问题时,按照这些线索进行排查,通常能够找到并解决问题。记住,一致性是解决编码问题的关键。

    解决fastreport中文显示不全和导出乱码

    总的来说,解决FastReport的中文显示不全和导出乱码问题,需要从两个方面入手:一是确保FastReport自身以及与其交互的数据源使用相同的字符编码;二是正确设置导出格式的编码参数,以适应目标格式的编码要求。同时,...

    乱码问题深度分析课题划分

    本文将深入探讨乱码问题的根源、常见场景以及解决策略,旨在为IT从业者提供一个全面的理解框架。 #### 1. 字符集与乱码现象 乱码,通常是指计算机系统或软件在处理文本时,由于字符编码不一致或转换错误,导致显示...

    解决java所有中文乱码集合

    本集合旨在全面解析和解决各种中文乱码问题,帮助开发者有效地理解和应对这类问题。 一、乱码产生的原因 1. 编码与解码不一致:文件或数据在编码时采用了一种字符集(如GBK),但在读取或显示时使用了另一种字符集...

    gbk汉字编码拼音对照表21004个字全.zip

    GBK汉字编码是中文字符编码的一种标准,全称为“汉字内码扩展规范”(Gbk,即Great Chinese Binary Code)。它是基于GB2312编码的扩展,兼容GB2312的同时增加了许多GBK独有的字符,总共包含了21004个汉字以及一些...

    Java中的中文编码问题

    ### Java中的中文编码问题 #### 一、引言 在软件开发过程中,特别是涉及多语言环境的应用时,字符编码问题常常成为开发者的头疼之事。Java作为一种广泛应用的编程语言,在处理多语言尤其是中文字符时,其编码问题...

    jsp中文乱码的解决方案

    总之,解决JSP中文乱码问题的关键在于确保所有环节的编码设置一致,并使用支持中文的编码格式,如UTF-8。通过以上步骤,大部分乱码问题都能得到妥善解决。在实际开发过程中,还需结合具体情况进行调整,以确保数据的...

    fastreport4.10.5 已经修正中文乱码问题

    《FastReport 4.10.5:解决中文乱码问题及全面支持D4-D15版本》 FastReport是一款强大的报表设计工具,尤其在.NET和Delphi开发环境中备受推崇。其最新版本4.10.5针对先前版本中可能出现的中文乱码问题进行了修复,...

    关于Java Web中中文乱码问题的探讨.pdf

    本文针对Java Web开发中字符编码问题进行探讨,主要围绕字符编码的种类、设置方式以及不同页面类型的代码编写差异,分析中文乱码的成因,并提出解决方案,旨在为初学者提供解决中文乱码问题的思路。 首先,计算机...

    RBuilder报表打印中文换行出乱码的真正解决方法

    总的来说,处理RBuilder报表打印中文乱码的问题需要深入理解字符编码原理,以及如何在不同系统环境中进行适配。通过检查和调整相关设置、升级组件或使用正确的编码转换函数,可以避免这种痛苦的编程体验,确保报表的...

    gbk汉字编码拼音对照表2万多xls格式可导入数据库

    GBK汉字编码是中文字符编码的一种标准,全称为“汉字内码扩展规范”(GB 18030-2000),它是GB2312编码的扩展,旨在兼容更多的汉字以及少数民族文字。GB2312仅包含了6763个常用汉字,而GBK则扩展到了20902个汉字,...

    JSP中文乱码解决集锦

    本篇文章将深入探讨如何解决JSP中的中文乱码问题,结合个人学习经验及网络资源,提供全面的解决方案。 1. **理解字符编码** - UTF-8是最常见的编码格式,支持全球大部分语言,包括中文。 - ISO-8859-1是英文为主...

    GBK编码下jQuery_Ajax中文乱码解决方案

    在Web开发过程中,使用Ajax技术与服务器端交互数据时经常会遇到字符集编码的问题,尤其是在使用GBK编码的环境中,通过jQuery发起的Ajax请求往往会导致中文乱码的情况出现。这不仅影响用户体验,也给开发工作带来了...

    unicode中文编码表

    - **4F00 - 50FF**: 在这部分区间中,我们可以看到不仅有汉字的编码,还混杂了一些拉丁字母和其他符号,这表明Unicode不仅仅限于汉字编码,还包括其他字符集的支持。 - **5100 - 53FF**: 这个区间的编码更加稀疏,...

    MySQL数据库跨越式升级中乱码问题分析及解决.pdf

    MySQL数据库在进行跨越式升级时,可能会遇到中文乱码问题,这主要是由于字符集设置不当导致的。MySQL在不同版本之间对多语言支持的改变,特别是从4.0.x到4.1及以上版本,引入了对Unicode(如UTF-8)更全面的支持,...

    Asp.net中的页面乱码的问题

    这样处理后,文件名会以UTF-8编码的形式传递给客户端,从而避免乱码问题。 #### 3. 数据库函数与字符集转换 在提供的代码片段中还涉及到了数据库函数和字符集转换的相关内容,这表明在数据库层面也存在字符集不...

    中文乱码.docx

    综上所述,通过正确设置`file.encoding`参数为UTF-8,可以在很大程度上解决由字符编码不一致导致的中文乱码问题。同时,开发者还应注意在修改配置前进行充分的准备和测试工作,确保系统的稳定性和兼容性。

Global site tag (gtag.js) - Google Analytics