• 解决服务器返回JSON数据中文乱码问题


            还是编码的问题.

            下午试了一下谷歌搜索的 REST 服务, 接口是 "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=<search item>, 过程也很简单: 将你要搜索的内容经过 UrlEncode 之后代替<search item>, 然后发出一个 GET 请求, 就应该得到该搜索内容的 JSON 数据. 比如我搜索 "Create Chen", 在浏览器中可以看到返回如下数据:

    {"responseData": {"results":[{"GsearchResultClass":"GwebSearch","unescapedUrl":"http://www.cnblogs.com/technology/","url":"http://www.cnblogs.com/technology/","visibleUrl":"www.cnblogs.com","cacheUrl":"http://www.google.com/search?q\u003dcache:wymiOeNCuYMJ:www.cnblogs.com","title":"\u003cb\u003eCreate Chen\u003c/b\u003e - 博客园","titleNoFormatting":"Create Chen - 博客园","content":"posted @ 2011-05-26 15:57 \u003cb\u003eCreate Chen\u003c/b\u003e 阅读(1206) | 评论(30) | 编辑 \u003cb\u003e...\u003c/b\u003e posted @ 2011-05-22 20:49 \u003cb\u003eCreate Chen\u003c/b\u003e 阅读(1781) | 评论(26) | 编辑

    ...省略以下内容...

            展示上一段的目的是为了说明在浏览器里, 数据包含中文的话, 还是显示正常的, 原因很简单: 我浏览器设置的默认编码就是 Unicode(UTF-8), 当然能正确显示中文.

            为了更好的展示数据, 我按照<Programming ASP.NET 3.5>里将在程序中获得的 JSON 数据序列化了一下, 没想到总是在序列化的时候出错, 只有搜索结果不包含中文的时候才运行正常. 代码如下:

    //...
    //GoogleSearchResponse的一些构造
    //...
    
    protected void btnSearch_Click(object sender, EventArgs e)
    {
        WebClient wc = new WebClient();
        Response.Write(wc.Encoding.ToString());
        wc.Headers.Add(HttpRequestHeader.Referer, Request.Url.ToString());
        string url = string.Format("http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q={0}",
            Server.UrlEncode(txtSearchFor.Text));
        var json = wc.DownloadString(url);
        GoogleSearchResponse sechResponse = null;
        using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
        {
            DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(GoogleSearchResponse));
            sechResponse = jsonSerializer.ReadObject(ms) as GoogleSearchResponse;
        }
        StringBuilder sb = new StringBuilder();
        foreach (GoogleResult res in sechResponse.responseData.results)
        {
            sb.AppendFormat("<a href='{0}'>{1}</a><br />", res.unescapedUrl, res.title);
        }
        lblResults.Text = sb.ToString();
    }

            经过调试发现在代码高亮的那一行, json字符串已经是乱码了. 因此我查看了 WebClient 的 DownloadString 方法:

            This method retrieves the specified resource. After it downloads the resource, the method uses the encoding specified in the Encoding property to convert the resource to a String. This method blocks while downloading the resource. To download a resource and continue executing while waiting for the server's response, use one of the DownloadStringAsync methods.

            前面两句说在下载到资源 (应该是 Byte[]) 后, 这个方法将会调用默认的编码方式将资源转化成 String. 好吧, 我来看看默认的编码方式是不是 UTF-8. 往往默认的编码方式是由操作系统和地区决定的, 在我的机器上测试后得知默认的编码方式不是 UTF-8, 是 System.Text.DBCSCodePageEncoding, 尽管编码方式不是 UTF-8, 但除了中文集字符, 这种编码方式确实还能识别出 Unicode 类型的编码, 前提是文件开头要有 BOM 信息, 关于能从 BOM 中获得哪些信息, 如下:

    Unicode         0xFF, 0xFE
    BE-Unicode    0xFE, 0xFF
    UTF8        0xEF, 0xBB, 0xBF

            就是这样的一个对应关系, 但我发现服务器返回的 JSON 数据并没有这样的 BOM 信息:

            因此, 我需要在程序中设置一下 WebClient 的 Encoding 属性, 将它设为 Encoding.UTF8, 运行正常.

            但回过头来看看, 程序似乎在 DownloadString 方法中将下载到的 Byte[] 转成一个 String, 紧接着又将这个 String 转换成 Byte[] 存进内存中, 可以直接调用 DownloadData 方法的, 将 DownloadData 方法下载到的数据直接存储到内存中, 然后再做进一步的序列化处理, 这样就省去了两次类型转换的操作.

            关于编码, 前几天还看到了一个笑话, 也不知道是真的还是假的:

            以Windows中文版为例。从英文版移植到中文版,并不只是翻译菜单那么简单,许多源代码都得重新改写。比如Word里打完一行字会自动换行,可英文是单字节的,中文却是双字节,一个“好”字,就很可能“女”在上一行末尾,“子”却到了下一行开头。——唐骏 <我的成功可以复制> P89

    作者:Create Chen
    出处:http://technology.cnblogs.com
    说明:文章为作者平时里的思考和练习,可能有不当之处,请博客园的园友们多提宝贵意见。
    知识共享许可协议本作品采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可。

  • 相关阅读:
    Nutch是个不错的选择
    Ext分页之php中,真分页显示
    php上传zip文件在线解压文件在指定目录下,CI框架版本
    php中使用mysql_fetch_array输出数组至页面中展示
    php中使用mysql_fetch_object向页面输出结果,总结!
    function $(id){ return document.getElementById(id); }导致所有的js不能用解决办法。。。。
    Html标签中Alt和Title都是提示性语言标签
    hdu3948(后缀数组)
    poj1743(后缀数组)
    spoj687(后缀数组)
  • 原文地址:https://www.cnblogs.com/technology/p/2067203.html
Copyright © 2020-2023  润新知