`
huangshanghua
  • 浏览: 56979 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

中文乱码问题

    博客分类:
  • java
阅读更多
1、字符编码   
    在计算机中任何数据都是以二进制存储的,要存储一个字符就要对它进行编码,用一个二进制数与这对应,这种对应的规则,就是字符的编码。编码的规则有很多种,一种规则所编码的“字符”的集合就叫做“字符集”。在制定编码标准的时候,“字符的集合”和“编码”一般都是同时制定的,因此,平时我们所说的“字符集”,例如GB2312、GBK和JIS等,除了有“字符的集合”这层含义外,同时也包含了“编码”的含义。
    最早出现的编码是ASCII码,因为早期计算机系统只支持英语。后来每个国家(或区域)规定了计算机信息交换用的字符编码集,例如中国的GB2312等作为自己国家/区域内信息处理的基础。在程序读取字符到输出字符的过程中,就需要在不同的字符集之间进行转换,这个时候就容易出现乱码,因此要了解乱码是如何产生的,首先要了解各种字符编码。下面对这些编码做一个简单介绍。
(1)、ASCII
    ASCII码是《美国标准信息交换码》,简称ASCII,它总共规定了128个字符号所对应的数字代码,使用了7位二进制的位来表示这些数字。其中包含了英文的大小写字母、数字和标点符号常用的字符,数字代号从0~127。
(2)、ISO8859
    ASCII码解决了英语国家的字符问题,可是欧洲各个国家的字符问题还没有解决,例如法语中就有许多英语中没有的字符,为了解决该问题,国际标准化组织的ISO8859标准应运而生,在ISO8859的编码表中,编号0~127与ASCII保持兼容,编号128~159共32个编码保留给扩充定义的32个扩充控制码,160为空格,161~255的95个数字用于新增加的字符代码。由于在一张码表中只能增加95种字符的代码,因此ISO8859实际上不是一张码表,而是一系列标准,包括14个字符码表。例如,西欧的常用字符就包含在ISO8859-1字符表中,在ISO8859-7中则包含了ASCII和现代希腊语字符。
(3)、GB2312和GBK
    GB2312是中国国家标准汉字信息交换用编码,简称国标码,标准号为GB2312-80。
中国的文字不是拼音文字,汉字的个数的数万之多,远远超过区区256个字符,ISO8859无能为力,但是通过借鉴ISO8859的编码思想,研究人员解决了中文的编码问题。GB2312使用两个字节来表示一个中文,在每个字符的256种可能中,为了与ASCII保持兼容,低于128的我们不使用。借鉴ISO8859的设计方案,只使用从160以后的96个数字,两个字节分成高位和低位,高位的取值范围从176~247共72个,低位从161~254共94个,这样,两个字节就有72*94=6768种可能,即可表示6768种汉字。
    BG2312-80仅收录了6763个汉字,还有许多汉字没有被收录进去,为了对更多的字符进行编码,全国信息技术化技术委员会于1995年12月1日颁布了《汉字内码扩展规范》,简称GBK。在GBK1.0中共收录了21886个汉字和图形符号,微软公司的window95系统的简体中文版开始即支持GBK编码。GBK向下与GB2312完全兼容,向上支持ISO10646国际标准。
(4)、UNICODE
    每个国家和地区都规定了计算机信息交换编码,这就造成了不同编码国家、地区之间交流上的困难,如果全世界都使用统一的编码表就好了,为此UNICODE组织发布了UNICODE编码。这种编码使用双字节符号数对每一个字符进行编码,在UNICODE3.0.1中包含了49194个字符,将来,UNICODE中还会增加更多的字符。UNICODE的全称是“Universal Multiple-Octet Coded Character Set”,简称UCS。
(5)、UTF-8
    使用UNICODE编码,一个英文字符也要占据两个字节,对于英文信息而言就增加了一倍数据量,为了减少存储和传输英文数据的数据量,美国人又制定了一系列用于传输和保存UNICODE的编码标准UTF,这些编码称为UCS传输格式码,也就是将UCS的编码通过一定的转换来达到使用的目的。常见的有UTF-7、UTF-8、UTF-16等。其中UTF-8编码得到了广泛的应用,UTF-8的全名是UCS Transformation Format 8,即UCS编码的8位传输格式,就是使用单字节的方式对UCS进行编码,使UNICODE编码能够在单字节的设备上正常进行处理。
UTF-8编码是变长的编码,对不同的UNICODE可能编成不同的长度。
    从理论上来说,这些根据字符集设置而进行的字符转换不应该产生太多的问题,而事实上由于应用程序的实际运行环境不同,UNICODE和各个本地字符集的补充、完善以及系统或应用程序实现的不规范,转码时还是会经常出现问题而导致乱码。
2、乱码产生的原因  
    Java语言内部是用UNICODE表示字符的,遵守UNICODE V2.0。Java程序无论是以字符流读/写磁盘文件,还是向URL转接写HTML信息,或从URL连接读取参数值,都会由UNICODE作为中介和本地字符编码进行转换。
    在WEB应用中,浏览器、WEB服务器、WEB应用程序和数据库等各个部分都有可能使用不用的字符集,字符在不同的字符集之间进行转换时,就有可能出现乱码问题。例如一个中文字符“中”要转换为ISO-8859-1编码,在Java中先读取到的是中文字符的GBK编码“0xD6D0”,转换为UNICODE码为“0x4E2D”,再从UNICODE编码转换ISO-8859-1编码,如果ISO-8859-1编码中没有对应的“0xD6D0”,于是就得到“0x3F”,也就是我们经常在页面上看到一堆“?”的原因。
    在WEB应用中,乱码可能在多个环节产生,下面针对可能出现乱码的几个环节,给出解决的方案。
3、乱码解决方案
(1)、JSP页面最基本的乱码问题
运行下面的代码,会发现页面上出现的是乱码。
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ page contentType="text/html; charset=ISO8859-1"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>中文问题</title>
</head>
<body>
乱码问题
</body>
</html>
这段代码产生乱码的原因在于它有三处设置了编码格式,但是格式设置的不一致,因此导致了乱码,下面来分析这三处设置编码格式的作用。
<%@ page language="java" pageEncoding="UTF-8"%>
此处的pageEncoding="UTF-8"为JSP文件的存储格式。
<%@ page contentType="text/html; charset=ISO8859-1"%>
此处charset=ISO8859-1为JSP的解码格式。ISO8859-1是没有为汉字编码的,因此按UTF-8编码存储的文件如果用ISO8859-1编码格式编码,其中的中文字符就会因为找不到对应的编码而显示为乱码。所以JSP文件的存储格式和它的解码格式应该是一致的。
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
此处编码控制的是浏览器的解码方式,浏览器收到的只是一个字节流,它并不知道
页面是如何编码的,因此,需要一个机制来告诉浏览器页面的编码类型,标准的机制是使用<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">来指定页面的编码,当浏览器读取页面遇到这样的指示时,将使用这里制定的编码方式重新加载页面。
     因此只要把三处的都设置为UTF-8或GBK即可解决乱码问题。
(2)、表单使用POST提交方式提交后接收到的是乱码
   WEB容器在内部编码格式是ISO8859-1,在POST方式提交时,默认的提交编码格式是ISO8859-1,这样接收到的中文信息就会是乱码,解决方式如下:
   在请求页面上开始处,执行请求和编码代码:
   request.setCharacterEncoding(“GBK”);
    把提交内容的字符集高为GBK,这样接受此参数的页面就不必再转码了,直接使用即可得到汉字参数。
    在每一个接受提交的JSP页面及Servlet中都加这样的代码是比较烦人的,可以用过滤器设置request和response的setCharacterEncoding方法来解决这个问题。
例:过滤器解决问题
public class setEncodeingFilter extends HttpServlet implements Filter {
private FilterConfig config;
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("GBK");
response.setCharacterEncoding("GBK");
chain.doFilter(request, response);
}

@Override
public void init(FilterConfig config) throws ServletException {
this.config = config;
}
}
这个过滤器中已经在doFilter方法中直接设置了统一使用GBK编码,然后在web.xml国配置过滤器:
<filter>
<filter-name>setEncodeingFilter </filter-name>
<filter-class>setEncodeingFilter(过滤器的全路径)</filter-class>
</filter>
<filter-mapping>
<filter-name>setEncodeingFilter </filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<url-pattern>/*</url-pattern>表示所有的页面都要经过此过滤器过滤,这样就不用在JSP和Servlet中设置encoding了。
(3)、表单使用GET方式导致的乱码的处理方式
如果使用GET方式提交中文,接受参数的页面也会出现乱码,原因是web容器会以GET方式的默认编码方式ISO8859-1对汉字进行编码,编码后追加到URL,导致接受页面得到的参数为乱码。 因为在进入URL之前已经进行了ISO8859-1的编码处理,所以需要在得到参数值后进行编码转换:
     String name = request.getParameter("name");
name = new String(name.getBytes("ISO8859-1"),"GBK");
(4)、数据库中读取和存储中文时的乱码问题
大多数的JDBC驱动都是默认IS-O8859-1为数据的传输编码格式,而数据库本身又有自己的字符集,因此在数据库读写中文数据库时也经常会出现筹码人。
流行的关系数据库系统都支持数据库Encoding,即在创建数据库时可以指定其自己的字符集设置。数据库的数据以指定的编码形式存储。当应用程序访问数据时,在入口和出口处都会有Encoding转换。对于中文数据,数据库字符编码的设置应当保证数据的完整性。
GB23212、GBK和UTF-8等都是可选的数据库Encoding,在JSP/Servlet编程时,可以先用数据库管理系统提供的管理功能检查其中的中文数据是否正确。
分享到:
评论

相关推荐

    中文乱码问题分析 自己总结的

    中文乱码问题分析 中文乱码问题是 Java 和 JSP 开发中的一种常见问题,主要是由于 Java 和 JSP 源文件的保存方式是基于字节流的,而编译成 class 文件过程中,使用的编码方式与源文件的编码不一致所致。在 Java ...

    FORM表单中文乱码问题分析与解决

    FORM表单中文乱码问题分析与解决 在 Web 开发中,中文乱码问题是一个常见的问题,尤其是在FORM表单传递参数时。这个问题的根本原因是对中文的编码与解码方式不一致。我们可以理解为对中文的加密与解密的密钥不一致...

    解决JSP中文乱码问题

    解决 JSP 中文乱码问题 解决 JSP 中文乱码问题是一个很常见的问题,在 JSP 开发过程中,经常出现中文乱码的问题,可能一至困扰着大家。下面我们将详细讨论 JSP 中文乱码问题的成因和解决方法。 JSP 中文乱码问题的...

    hadoop中文乱码问题

    【Hadoop中文乱码问题详解】 在大数据处理领域,Hadoop是一个不可或缺的开源框架,它提供了分布式存储(HDFS)和分布式计算(MapReduce)的能力。然而,在处理包含中文字符的数据时,用户可能会遇到中文乱码的问题...

    sqlite3 for delphi 解决中文乱码问题

    "sqlite3 for delphi 解决中文乱码问题"这个主题,正是针对这一问题提供了解决方案。这里我们将详细探讨SQLite3在Delphi中的应用,中文乱码的成因,以及如何通过自定义修改来解决这个问题。 首先,SQLite3是一个轻...

    Ajax中文乱码问题解决方案

    然而,在处理中文字符时,Ajax请求可能会遇到乱码问题,这主要是由于编码格式不一致或者处理不当导致的。本文将深入探讨Ajax中文乱码问题的成因,并提供一系列解决方案。 **一、问题原因** 1. **编码格式不一致**...

    MySQL数据库系统中文乱码问题及解决方案.pdf

    MySQL数据库系统中文乱码问题及解决方案 MySQL数据库系统中文乱码问题是指在使用MySQL数据库系统时,中文字符在存储、传输和显示过程中出现乱码的问题。这种问题的出现是由于字符集和编码方式的不兼容所致。 在...

    soapUI输入中文显示为乱码,响应报文中文乱码问题解决方法.txt

    soapUI输入中文显示为乱码 响应报文中文乱码问题解决方法

    java中文乱码问题详解--- java中文乱码问题详解

    ### Java中文乱码问题详解 #### 一、中文问题的来源与背景 计算机技术发展初期,操作系统主要支持单字节的ASCII字符集。随着全球化进程加快和技术进步,为支持多种语言,尤其是双字节编码的语言(如中文),提出了...

    使用ODBC中文乱码问题.docx

    ODBC中文乱码问题解决方案 在使用ODBC对数据库进行中文字符串插入时,经常会遇到中文字符串显示乱码的问题。本文将通过对该问题的分析和解决方案,帮助读者更好地理解ODBC中文乱码问题的成因和解决方法。 一、问题...

    ArcGIS 10.X导出dbf文件时出现中文乱码问题修复补丁.rar

    本压缩包文件“ArcGIS 10.X导出dbf文件时出现中文乱码问题修复补丁.rar”就是针对这个问题提供的一种解决方案。 标题中提到的“ArcGIS 10.X”指的是ArcGIS软件的10.x版本系列,这个系列包括10.0、10.1、10.2直至...

    editplus插件htmlFormatter.js解决中文乱码问题

    首先,我们了解下中文乱码问题的背景。在处理包含中文字符的HTML文件时,如果没有正确设置编码或者在格式化过程中编码转换不当,就可能出现中文乱码现象。这不仅影响代码的可读性,也可能导致程序运行错误。因此,...

    struts 中文乱码问题解决

    在IT领域,特别是Web开发中,Struts框架作为Java Web应用的一个重要组成部分,其在处理中文字符时常常遇到乱码问题。这个问题不仅影响了用户体验,也增加了开发者的调试难度。本文将深入探讨Struts框架中中文乱码的...

    JSP中文乱码问题解决办法

    JSP 中文乱码问题解决办法 JSP 页面中中文乱码问题是指在 JSP 页面中使用中文时,页面显示乱码的现象。这种问题的解决办法可以从多方面入手,包括设置页面的字符编码、使用 POST 方式提交表单、使用 GET 方式提交...

    解决linux下oracle中文乱码问题,添加中文支持

    解决linux下oracle中文乱码问题,添加中文支持解决linux下oracle中文乱码问题,添加中文支持解决linux下oracle中文乱码问题,添加中文支持解决linux下oracle中文乱码问题,添加中文支持解决linux下oracle中文乱码...

    linux下中文乱码问题

    Linux 下中文乱码问题解决方法 Linux 操作系统中,中文乱码问题是一个常见的问题,它是由系统集成的字符集引起的。由于不能正确地使用相对应字符的字符集,因此 OS 不能识别出文字,导致了乱码。解决这个问题的方法...

    解决sql anywhere 11 汉字乱码问题

    在开发基于C++ Builder的...通过以上分析和步骤,你应该能够有效地解决SQL Anywhere 11中遇到的汉字乱码问题,确保你的数据库应用能够正确处理中文数据。在实际操作中,如果遇到困难,建议查阅官方文档或寻求社区支持。

Global site tag (gtag.js) - Google Analytics