如何将json字符串解码为UTF-8?

时间:2019-04-26 09:58:44

标签: android json dart flutter

我已经使用json一段时间了,问题是我解码的字符串编码为Latin-1,但我无法使其用作UTF-8。因此,某些字符显示不正确(例如'显示为')。

我在这里已经阅读了一些关于stackoverflow的问题,但是它们似乎不起作用。

我正在使用的json结构如下(它来自YouTube API):

...
"items": [
  {
   ...
   "snippet": {
    ...
    "title": "Powerbeats Pro “Totally Wireless” Except when you need a wire",
    ...
    }
   }
  ]

我使用以下代码进行编码:

response = await http.get(link, headers: {HttpHeaders.contentTypeHeader: "application/json; charset=utf-8"});
extractedData = json.decode(response.body);
dataTech = extractedData["items"];

然后我尝试将第二行更改为:

extractedData = json.decode(utf8.decode(response.body));

但这给了我关于格式错误的错误。所以我将其更改为:

extractedData = json.decode(utf8.decode(response.bodyBytes));

这不会引发错误,但是也不能解决问题。玩头文件都不行。

我希望数据像现在一样存储在dataTech中,但编码为UTF-8。我在做什么错了?

2 个答案:

答案 0 :(得分:0)

首先请注意:UTF-8通常是 external 格式,并且通常由字节数组表示。这就是您可能会通过网络发送的HTTP响应的一部分。在内部,Dart将字符串存储为UTF-16代码点。 utf8编码器/解码器在内部格式字符串和外部格式字节数组之间进行转换。

这就是为什么您使用utf8.decode(response.bodyBytes)的原因;提取原始正文字节并将其转换为内部字符串。 (response.body基本上也这样做,但是它基于响应头字符集选择bytes-> string解码器。当缺少此字符集头(通常是这样)时,http包会选择Latin-1 ,如果您知道响应位于不同的字符集中,则显然不起作用。)通过自己使用utf8.decode,您将覆盖http做出的(可能是错误的)选择,因为您知道该特定服务器始终发送UTF-8。 (当然不会!)

另一方面,在 request 上设置内容类型标头很少有用。您通常不会发送任何内容-因此它没有类型!但这不会影响服务器将发回给您的内容类型或内容类型字符集。 accept标头可能就是您想要的。这向服务器暗示了您想要返回哪种类型的内容-但并非所有服务器都尊重它。

那么为什么您的特殊字符仍然不正确?尝试在解码之前打印utf8.decode(response.bodyBytes)。它在控制台中看起来正确吗? (针对这种类型的问题创建一个简单的Dart命令行应用程序非常有用;我发现在一个简单的10行Dart应用程序中设置断点和检查变量更加容易。)尝试使用Wireshark之​​类的方法来捕获网络上的字节(同样,对于使用简单的Dart应用程序很有用)。或者尝试使用Postman发送相同的请求并检查响应。

您如何尝试显示字符。如果可能仅仅是您使用的字体没有它们。

答案 1 :(得分:0)

只需添加标题:'Accept':'application / json; charset = UTF-8'; 对我有用