从API反序列化JSON值 - 卷曲与方括号

时间:2018-04-19 17:32:26

标签: json dart flutter

我正在努力整合来自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库似乎更喜欢方括号[而不是卷曲的{{/ p>

当我尝试对大括号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

但是,如果我做这个愚蠢的事情(解析方括号为卷曲并添加第一个字符串&#34;欢迎&#34; ...

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

......工作正常

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

我认为如果Root / Welcome对象中的Weather对象列表不存在,这可能会有效。因为这个对象包含一个对象列表,这有点令人困惑吗?这是我对象中的BuiltList

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

1 个答案:

答案 0 :(得分:1)

guard let json = try? JSONSerialization.jsonObject(with:data, options .mutableContainers) as? [String:Any] else { return } 用于列表/数组,[]用于地图。使用{},您可以使用built_valueBuiltList类型的属性。

BuiltMap不返回类的实例,它只是从JSON字符串中生成列表,映射和单独的原始值。

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

默认情况下,

JSON.decode(...)具有减少的JSON格式,与您的JSON不兼容。为此,您需要注册StandardJsonPlugin(另请参阅https://github.com/google/built_value.dart/issues/171

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