【问题标题】:Deserializing a JSON value from an API - curly vs. square brackets从 API 反序列化 JSON 值 - 大括号与方括号
【发布时间】:2018-09-30 07:18:19
【问题描述】:

我正在努力从一个 API 中整合一些天气信息,并在其中获得这样的返回值......

{"coord":{"lon":-85.6,"lat":43.05},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04d"}],"base":"stations","main":{"temp":277.33,"pressure":1010,"humidity":65,"temp_min":276.15,"temp_max":279.15},"visibility":16093,"wind":{"speed":5.7,"deg":100,"gust":8.2},"clouds":{"all":75},"dt":1524076680,"sys":{"type":1,"id":1410,"message":0.0043,"country":"US","sunrise":1524048860,"sunset":1524097768},"id":420018526,"name":"Grand Rapids","cod":200}

我创建了一个 built_valuebuilt_collection 对象来反序列化。如果我“手动”构建对象并将其序列化,然后 JSON 对其进行编码......

var w = new Welcome((b) => b
 ..id = 420018526
 ..name = "Grand Rapids"
 ..weather.add(new Weather((w)=>w
    ..id = 803
    ..main = "Clouds"
    ..description = "broken clouds"
    ..icon = "04d"
  ))
 ..cod = 200
 ..coord.lat = 43.05
 ..coord.lon= -85.6
 ..base = 'stations'
 ..main.temp = 277.33
 ..main.pressure = 1010
 ..main.humidity = 65
 ..main.temp_min = 276.15
 ..main.temp_max = 279.15
 ..visibility = 16093
 ..wind.speed = 5.7
 ..wind.deg = 100
 ..wind.gust = 8.2
 ..clouds.all = 75
..dt = 1524076680
..sys.type = 1
..sys.id = 1410
..sys.message = 0.0043
..sys.country = "US"
..sys.sunrise = 1524048860
..sys.sunset = 1524097768
 );

var ws = serializers.serialize(w);
var wsj = JSON.encode(ws);

我得到了这样的东西......

["Welcome","coord",["lon",-85.6,"lat",43.05],"weather",[["id",803,"main","Clouds","description","broken clouds","icon","04d"]],"base","stations","main",["temp",277.33,"pressure",1010,"humidity",65,"temp_min",276.15,"temp_max",279.15],"visibility",16093,"wind",["speed",5.7,"deg",100,"gust",8.2],"clouds",["all",75],"dt",1524076680,"sys",["type",1,"id",1410,"message",0.0043,"country","US","sunrise",1524048860,"sunset",1524097768],"id",420018526,"name","Grand Rapids","cod",200]

... 看起来非常相似,但您会注意到 dart:convert JSON 库似乎更喜欢方括号 [ 而不是大括号 {

当我尝试反序列化大括号 wsjdA = JSON.decode(wJson); 时出现错误

type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Welcome' of 'wsjdA' where
  _InternalLinkedHashMap is from dart:collection
  String is from dart:core
  Welcome is from package:ex_models/src/weather.dart

但是如果我做这个愚蠢的事情(解析出方括号为花括号并添加第一个字符串“欢迎”......

var wJsonB= '["Welcome",' + wJson
  .replaceAll('{', '[')
  .replaceAll('}', ']')
  .replaceAll(':', ',')
  .substring(1);

...效果很好

我是否遗漏了什么 - 有没有更简单的方法在 dart 中进行 JSON/对象反序列化。我真的希望能够以标准方式将有效的 JSON API 响应解析为 dart 对象,而无需手动解析。

如果不是根/欢迎对象中的天气对象列表,我认为这可能有效。因为这个对象包含一个对象列表,这有点混乱吗?这是我的对象中的BuiltList

我已经在使用 built_value 对象和 built_collections 并使用 dart:convert 库。想知道我是否遗漏了什么?

【问题讨论】:

    标签: json dart flutter


    【解决方案1】:

    [] 用于列表/数组,{} 用于映射。使用built_value,您可以使用BuiltListBuiltMap 类型的属性。

    JSON.decode(wJson); 不返回类的实例,它只是从 JSON 字符串中生成列表、映射和分离原始值。

    built_value 有自己的序列化,从 JSON.decode(...) 返回到具体的类实例。

    built_value 默认情况下具有简化的 JSON 格式,与您的 JSON 不兼容。为此,您需要注册StandardJsonPlugin(另请参阅https://github.com/google/built_value.dart/issues/171

    有关使用built_value 进行序列化的详细信息,请参阅https://medium.com/dartlang/darts-built-value-for-serialization-f5db9d0f4159

    【讨论】:

    • 不错。感谢 StandardJsonPlugin 提示 ... 更接近最终的 standardSerializers = (serializers.toBuilder()..addPlugin(new StandardJsonPlugin())).build(); var wJson2 = '{"\$":"Welcome",' + responseText.substring(1); var wsjdA = JSON.decode(wJson2);欢迎 wsdcA = standardSerializers.deserialize(wsjdA);我唯一缺少的部分是它似乎需要/需要第一个元素 {"$","Welcome",其中 "Welcome" 是类名 - 所有其余部分都按照广告宣传 - 正在处理这个问题。
    • 最终值 = standardSerializers.deserializeWith(Welcome.serializer, JSON.decode(responseText));使用“deserializeWith”添加了上下文,因此不需要“鉴别器”($/Welcome) - 将此标记为我的答案 - 谢谢!此外,将“standardSerializers”添加到我现有的 serializers.dart 中,这样“dart/stock”和“standardized”序列化程序都在类中,并且将在其他地方有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多