您的位置广东网盟 > 文章资讯 > 软件应用 > 编程开发 > VC/VC++ > 文章内容

中文编码问题全面解析

作者:佚名  来源:不详  发布时间:2008-7-30 21:36:35

  基于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源文件

package org.kyle.web.sample;

import java.io.IOException;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.UnavailableException;

public class SetCharacterEncodingFilter implements Filter

{

    /**

     * The default character encoding to set for requests that pass through

     * this filter.

     */

    protected String encoding = null;

 

    /**

     * The filter configuration object we are associated with. If this value

     * is null, this filter instance is not currently configured.

     */

    protected FilterConfig filterConfig = null;

 

 

    /**

     * Should a character encoding specified by the client be ignored?

     */

    protected boolean ignore = true;

 

    /**

     * Take this filter out of service.

     */

    public void destroy()

    {

        this.encoding = null;

        this.filterConfig = null;

    }

 

    /**

     * Select and set (if specified) the character encoding to be used to

     * interpret request parameters for this request.

     *

     * @param request The servlet request we are processing

     * @param result The servlet response we are creating

     * @param chain The filter chain we are processing

     *

     * @exception IOException if an input/output error occurs

     * @exception ServletException if a servlet error occurs

     */

    public void doFilter(ServletRequest request, ServletResponse response,

                         FilterChain chain)

 throws IOException, ServletException

 {

 

        // Conditionally select and set the character encoding to be used

        if (ignore || (request.getCharacterEncoding() == null))

        {

            String encoding = selectEncoding(request);

            if (encoding != null)

                request.setCharacterEncoding(encoding);

        }

 

 // Pass control on to the next filter

        chain.doFilter(request, response);

    }

 

 

    /**

     * Place this filter into service.

     *

     * @param filterConfig The filter configuration object

     *                  

     *encoding

     * UTF-8

     *

     */

    public void init(FilterConfig filterConfig) throws ServletException

    {

        this.filterConfig = filterConfig;

        this.encoding = filterConfig.getInitParameter("encoding");

        String value = filterConfig.getInitParameter("ignore");

        if (value == null)

            this.ignore = true;

        else if (value.equalsIgnoreCase("true"))

            this.ignore = true;

        else if (value.equalsIgnoreCase("yes"))

            this.ignore = true;

        else

            this.ignore = false;

    }

 

    /**

     * Select an appropriate character encoding to be used, based on the

     * characteristics of the current request and/or filter initialization

     * parameters. If no character encoding should be set, return

     * null.

     *

     * The default implementation unconditionally returns the value configured

     * by the encoding initialization parameter for this

     * filter.

     *

     * @param request The servlet request we are processing

     */

    protected String selectEncoding(ServletRequest request)

    {

        return (this.encoding);

    }

}

    /**

     * The default implementation unconditionally returns the value configured

     * by the encoding initialization parameter for this

     * filter.

     *

     * @param request The servlet request we are processing

     */

    protected String selectEncoding(ServletRequest request)

    {

        return (this.encoding);

    }

}

[1] [2]  下一页

Tags:广东网盟  
  •         用户名: 验证码: 验证码,看不清楚请点击刷新验证码 (注“”为必填内容。)


    文章评论: [ 查看全部 ] 网友评论
    关于网盟 | 网站帮助 | 广告合作 | 下载声明 | 友情连接 | 联系方式

    Copyright © 2003-2008 Gdwg.Net. All Rights Reserved .
    中国广东网管联盟设计维护.网站备案:粤ICP备08020875号