新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 讨论HTML、XHTML、Web2.0、Ajax、XUL, ExtJS, jQuery, JSON、Social Networking System(SNS)、Rich Internet Applications (RIA)、Tagging System、Taxonomy(tagsonomy,folkonomy)、XForms、XFrames、XInclude, XBL (XML Binding Language)等话题
    [返回] 中文XML论坛 - 专业的XML技术讨论区XML.ORG.CN讨论区 - XML技术『 HTML/XHTML/Ajax/Web 2.0/Web 3.0 』 → UTF-8 字符处理在 Web 开发中的应用 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 25765 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: UTF-8 字符处理在 Web 开发中的应用 举报  打印  推荐  IE收藏夹 
       本主题类别: Web架构    
     admin 帅哥哟,离线,有人找我吗?
      
      
      
      威望:9
      头衔:W3China站长
      等级:计算机硕士学位(管理员)
      文章:5255
      积分:18406
      门派:W3CHINA.ORG
      注册:2003/10/5

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    兴趣:
    * XML相关技术
    * 资料收集
    * Ontology Engineering
    * Web架构
    * SW Implementation
    给admin发送一个短消息 把admin加入好友 查看admin的个人资料 搜索admin在『 HTML/XHTML/Ajax/Web 2.0/Web 3.0 』的所有贴子 点击这里发送电邮给admin  访问admin的主页 引用回复这个贴子 回复这个贴子 查看admin的博客楼主
    发贴心情 UTF-8 字符处理在 Web 开发中的应用

    http://www-128.ibm.com/developerworks/cn/web/wa-lo-utf8/index.html?ca=drs-tp2906

    级别: 初级

    [URL=http://www-128.ibm.com/developerworks/cn/web/wa-lo-utf8/index.html?ca=drs-tp2906#author]殷 健[/URL], 软件工程师,IBM CSDL


    2006 年 7 月 27 日

    Web 应用要适应多语言的需求。不同国家的用户应该可以输入本国语言的字符, 同时 Web 应用又应该可以根据不同的区域设置来用多国语言显示页面。 当前,不同的语言有不同的编码方式来显示对应的语言信息,例如中文可以用 GB2312 编码来显示,日文可以用 Shift-JIS 编码来显示。但 UTF-8 编码方式几乎可以包括了所有的语言字符。用 UTF-8 编码来处理 Web 应用信息的输入和显示可以使不同 Web 应用之间的信息交互标准化,并且可以简化应用的开发过程。
    UTF-8 编码介绍

    UTF-8 编码是一种被广泛应用的编码,这种编码致力于把全球的语言纳入一个统一的编码,目前已经将几种亚洲语言纳入。UTF 代表 UCS Transformation Format.

    UTF-8 采用变长度字节来表示字符,理论上最多可以到 6 个字节长度。UTF-8 编码兼容了 ASC II(0-127), 也就是说 UTF-8 对于 ASC II 字符的编码是和 ASC II 一样的。对于超过一个字节长度的字符,才用以下编码规范:

    左边第一个字节1的个数表示这个字符编码字节的位数,例如两位字节字符编码样式为为:110xxxxx 10xxxxxx; 三位字节字符的编码样式为:1110xxxx 10xxxxxx 10xxxxxx.;以此类推,六位字节字符的编码样式为:1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx。 xxx 的值由字符编码的二进制表示的位填入。只用最短的那个足够表达一个字符编码的多字节串。例如:

    Unicode 字符: 00 A9(版权符号) = 1010 1001, UTF-8 编码为:11000010 10101001 = 0x C2 0xA9; 字符 22 60 (不等于符号) = 0010 0010 0110 0000, UTF-8 编码为:11100010 10001001 10100000 = 0xE2 0x89 0xA0


    [URL=http://www-128.ibm.com/developerworks/cn/web/wa-lo-utf8/index.html?ca=drs-tp2906#main]回页首[/URL]

    HTTP 通讯协议

    HTTP 请求

    在 HTTP 通讯中,在客户端发出的请求报文中,首先设置的是方法。方法是用来告诉服务器客户端发起的动作请求。在请求的报文头部,客户端还可以同时发送附加的信息,比如客户端使用的浏览器和客户端可以解释的内容类型等。这些信息可以被服务器端应用程序使用以生成响应。下面是一个 HTTP 请求消息的示例:


    图1. HTTP 请求消息头
    GET /intro.html HTTP/1.0
    User-Agent: Mozilla/4.0 (compatible; MSIE 4.0; Windows 95)
    Accept: image/gif, image/jpeg, text/*, */*
    Accept-language : zh
    Accept-Charset: iso-8859-1


    这个请求通过 GET 方法来获取资源 /intro.htm。User-Agent 提供了客户端浏览器的信息,同时 Accept 提供了客户端可以接受的媒体类型。Accep-language 指出了客户端浏览器的首选语言, Accept-Charset 提供了浏览器的首选字符集,服务器端程序能够根据客户端的要求来生成需要的响应。用户可以通过配置浏览器来设置首选语言。以 IE 为示例如下:


    图2. 浏览器首选语言设置
    按此在新窗口浏览图片

    当浏览器发出请求后,可以通过以下代码来读取客户端浏览器的首选语言和国家代码。


    图3. 服务器端 Servlet 读取浏览器首选国家和语言
    protected void insertproc(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException{
         Locale reqLocal = req.getLocale();
         System.out.println("The country is :" + reqLocal.getCountry());
         System.out.println("The language is :" + reqLocal.getLanguage());


    服务器端的输出结果为:


    图4. 服务器端 Servlet 读取浏览器首选国家和语言结果
    [06-3-10 14:56:32:516 CST] 6ce078f9 SystemOut     O The country is :CN
    [06-3-10 14:56:32:516 CST] 6ce078f9 SystemOut     O The language is :zh


    HTTP 响应

    当服务器端收到请求后,会处理请求并发回应答。服务器通过应答消息的头部来指明诸如服务器软件和相应的内容类型等信息。以下是一个应答消息头的示例:


    图5.HTTP 应答消息头
    Date: Saturday, 23-May-98 03:25:12 GMT
    Server: JavaWebServer/1.1.1
    MIME-version: 1.0
    Content-type: text/html; charset=UTF-8
    Content-length: 1029
    Last-modified: Thursday, 7-May-98 12:15:35 GMT


    Content-type 表明了应答消息的 MIME 类型和应答消息体的字符集,浏览器会用相应的字符集来显示消息内容。例如,在以上示例中字符集是 UTF-8,浏览器会用 UTF-8 编码来解析和现实返回的消息体。同时页面输入也会被用 UTF-8 编码。


    [URL=http://www-128.ibm.com/developerworks/cn/web/wa-lo-utf8/index.html?ca=drs-tp2906#main]回页首[/URL]

    Web 页面显示编码

    可以通过以下几种方式来设置内容类型。

    在 HTML 中设置页面的编码方式

    如果被访问的是一个静态的 HTML 页面。可以通过以下方式来设置页面的编码方式。


    图6. 设置页面编码的静态 HTML 文件
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <HTML>
    <HEAD>
    <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <TITLE>example.html</TITLE>
    </HEAD>
    <BODY>
    </BODY>
    </HTML>


    标记"<META http-equiv="Content-Type" content="text/html; charset=UTF-8">" 将应答消息头中 Content_type 设置为"text/html; charset=UTF-8".

    在 Servlet 中设置页面显示编码方式

    在 Servlet 中,我们可以通过以下方式来设置应答消息的内容类型。


    图7.设置页面编码的 Servlet 片断
    protected void insertproc(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException{
    resp.setContentType("text/html;charset=UTF-8");


    代码行"resp.setContentType("text/html;charset=UTF-8");"将应答消息头中 Content_type 设置为"text/html; charset=UTF-8"。

    在 JSP 中设置页面显示编码方式

    我们通过以下示例说明如何在 JSP 中设置页面的编码格式。


    图8. 设置业面编码的 JSP 页面指令
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>


    在这行的页面指令中的"text/html; charset=UTF-8"将应答消息中的"Content-type" 设置为"text/html; charset=UTF-8"。

    "pageEncoding"只是指明了 JSP 页面本身的编码格式,指明了 JSP 是以什么编码方式保存。容器在读取文件时将起转化为内部使用的 Unicode. 当应答发送回至浏览器时,容器会将内部使用的 Unicode 转化为在 Content-type 中指定的字符集。

    如果没有指定 PageEncoding,可以通过使用 Content-type 指定的字符集来解释 JSP 页面字节。

    为了能正常显示 UTF-8 编码的字符,要满足以下两个条件:

    1. 通知浏览器应答消息使用的字符集。

    2. 配置浏览器使其能有正常显示 UTF-8 编码的字体。


    [URL=http://www-128.ibm.com/developerworks/cn/web/wa-lo-utf8/index.html?ca=drs-tp2906#main]回页首[/URL]

    Web 页面输入编码

    HTML 的表单可以接受非西欧语言字符的输入。当需要创建一个需要接受非西欧语言字符输入的表单时,必须通知浏览器应该为用户输入使用哪个字符集,我们可以通过设置 page 指令的 contentType 属性来设置。

    我们需要注意的是,当表单被提交后,浏览器会将表单字段值转换为指定字符集对应的字节值,然后根据 HTTP 标准 URL 编码方案对结果字节进行编码。当使用 ISO-8859-1 编码时,任何 a 到 z, A 到 Z 和 0 到 9 之外的字符都会被转化为十六进制格式的字节值,并在前面加上一个百分号(%).例如,如果表单的字符集被设为 UTF-8, 字符"中文"被传递的编码格式为:"%E4%B8%AD%E6%96%87"。为了对输入的信息进行处理,容器必须知道浏览器是使用什么字符集对输入进行编码的。问题是当今多数的浏览器并不提供这种信息,因此你必须自己提供这种信息,并告诉容器用哪个字符集对输入进行解码。

    页面输入编码设定

    在本文第3部分中说明了如何设置页面的显示编码,在设置页面编码的同时,也就指定了页面的输入方式。如果页面的显示被设置为UTF-8,那么用户所有的页面输入都会按照 UTF-8 编码。

    页面输入输出过程编码设置

    服务器端程序在读取表单输入之前要设定输入编码。我们可以看一下示例。

    以下是一个用来提示用户输入的 JSP 页面:


    图9. 用以界面输入的 JSP 页面
    <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <HTML>
    <HEAD>
    <TITLE>insertdb.jsp</TITLE>
    </HEAD>
    <BODY>
    <P>
    <FORM METHOD=POST ACTION="./InsertDbProcDs">
    <TABLE>
    <TR>
    <TD>Name:</TD>
    <TD><input type="text" name="col2" value=""></TD>
    <TR>
    <TD><INPUT type="submit" value="submit"></TD>
    </TR>
    </TR>
    </TABLE>
    </RORM>
    </P>
    </BODY>
    </HTML>


    页面指令元素的属性 Content-type 值为"text/html; charset=UTF-8",这会向浏览器指明页面是按照 UTF-8 编码的,并且所有用户通过页面的输入也会按照 UTF-8 编码。被 Action 所触发的 Servlet 如下例所示。


    图10. 用以按 UTF-8 读取输入并输出的 Servlet
        protected void insertproc(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException{
       String test1 = req.getParameter("col2");
       PrintWriter out = resp.getWriter();
             resp.setContentType("text/html;charset=UTF-8");
       out.println("<HTML>");
       out.println("The input is " + test1);
       out.println("</HTML>");

        


    通过表单页面输入"中文"并提交表单,得到的结果为:


    图11.正确显示结果的页面
    按此在新窗口浏览图片

    如果我们注释掉语句:resp.setContentType("text/html;charset=UTF-8"), 如下例:


    图12. 用以按非 UTF-8 读取输入并输出的 Servlet
    protected void insertproc(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException{
    String test1 = req.getParameter("col2");
       PrintWriter out = resp.getWriter();
             //resp.setContentType("text/html;charset=UTF-8")
       out.println("<HTML>");
       out.println("The input is " + test1);
       out.println("</HTML>");
       


    输入"中文"并提交表单,得到的结果为:


    图13. 错误显示输入结果的页面
    按此在新窗口浏览图片

    页面不能正确显示 UTF-8 编码的字符。

    在被触发的 Servlet 中通过设置 resp.setContentType("text/html;charset=UTF-8") 来向浏览器指明输出的编码字符集为 UTF-8,浏览器会用正确的字符集来显示输出。如果 Servlet 中没有显示的调用 resp.setContentType("text/html;charset=UTF-8") 来设定输出字符集,浏览器将不能正确的解码和显示输出。


    [URL=http://www-128.ibm.com/developerworks/cn/web/wa-lo-utf8/index.html?ca=drs-tp2906#main]回页首[/URL]

    结论

    本文给出了一些在 Web 应用开发中如何显示和输入 UTF-8 编码字符的方法。便于读者在开发实践中参考。


    [URL=http://www-128.ibm.com/developerworks/cn/web/wa-lo-utf8/index.html?ca=drs-tp2906#main]回页首[/URL]

    参考资料

    参考资源:
    Java Servlet Programming([URL=http://www.oreilly.com/]O'Reilly Media. Inc[/URL])
    Java server Pages([URL=http://www.oreilly.com/]O'Reilly Media. Inc[/URL])

    相关资源:
    在developerworks 关于字符编码的文章:
    [URL=http://www.ibm.com/developerworks/cn/Websphere/library/techarticles/likejia/0510/]JAVA 编程/WAS 对多语言(双字节)的支持[/URL]
    [URL=http://www.ibm.com/developerworks/cn/java/java_chinese/]Java 编程技术中汉字问题的分析及解决[/URL]
    [URL=http://www.ibm.com/developerworks/cn/java/jsp_dbcsz/]JSP/Servlet 中的汉字编码问题[/URL]



    [URL=http://www-128.ibm.com/developerworks/cn/web/wa-lo-utf8/index.html?ca=drs-tp2906#main]回页首[/URL]

    关于作者

      殷健是一位 IBM CSDL 的软件工程师,目前从事企业电子商务应用的开发。


       收藏   分享  
    顶(0)
      




    ----------------------------------------------

    -----------------------------------------------

    第十二章第一节《用ROR创建面向资源的服务》
    第十二章第二节《用Restlet创建面向资源的服务》
    第三章《REST式服务有什么不同》
    InfoQ SOA首席编辑胡键评《RESTful Web Services中文版》
    [InfoQ文章]解答有关REST的十点疑惑

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/7/30 1:28:00
     
     kenneygg 帅哥哟,离线,有人找我吗?
      
      
      等级:大三(面向对象是个好东东!)(版主)
      文章:74
      积分:636
      门派:XML.ORG.CN
      注册:2005/5/4

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给kenneygg发送一个短消息 把kenneygg加入好友 查看kenneygg的个人资料 搜索kenneygg在『 HTML/XHTML/Ajax/Web 2.0/Web 3.0 』的所有贴子 引用回复这个贴子 回复这个贴子 查看kenneygg的博客2
    发贴心情 
    编码的确很重要的。有收获。
    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/7/30 5:26:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 HTML/XHTML/Ajax/Web 2.0/Web 3.0 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/3/29 10:50:10

    本主题贴数2,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    7,171.875ms