引用头文件
import ‘dart:convert’
通过http用get方法得到Json数据
以玩Android的banner数据为例:
//异步获取
var responseBody;
var url = 'https://www.wanandroid.com/banner/json';
var httpClient = new HttpClient();
var request = await httpClient.getUrl(Uri.parse(url));
var response = await request.close();
if (response.statusCode == 200) {
//得到Json格式的字符串
responseBody = await response.transform(utf8.decoder).join();
} else {
print("get json error");
}
//返回Json格式字符串,之后解析
return responseBody;
其中Json数据:
{
"data": [
{
"desc": "Android高级进阶直播课免费学习",
"id": 23,
"imagePath": "https://wanandroid.com/blogimgs/92d96db5-d951-4223-ac42-e13a62899f50.jpeg",
"isVisible": 1,
"order": 0,
"title": "Android高级进阶直播课免费学习",
"type": 0,
"url": "https://url.163.com/4bj"
},
{
"desc": "一起来做个App吧",
"id": 10,
"imagePath": "https://www.wanandroid.com/blogimgs/50c115c2-cf6c-4802-aa7b-a4334de444cd.png",
"isVisible": 1,
"order": 0,
"title": "一起来做个App吧",
"type": 1,
"url": "https://www.wanandroid.com/blog/show/2"
},
{
"desc": "",
"id": 6,
"imagePath": "https://www.wanandroid.com/blogimgs/62c1bd68-b5f3-4a3c-a649-7ca8c7dfabe6.png",
"isVisible": 1,
"order": 1,
"title": "我们新增了一个常用导航Tab~",
"type": 1,
"url": "https://www.wanandroid.com/navi"
},
{
"desc": "",
"id": 20,
"imagePath": "https://www.wanandroid.com/blogimgs/90c6cc12-742e-4c9f-b318-b912f163b8d0.png",
"isVisible": 1,
"order": 2,
"title": "flutter 中文社区 ",
"type": 1,
"url": "https://flutter.cn/"
}
],
"errorCode": 0,
"errorMsg": ""
}
结构(规则一)
用 [ 开头的是List of map
用 { 开头的是map
例子:
//list数组
[
"id":"487349",
"name":"Pooja Bhaumik",
"score" : 1000
]
//Map对象
{
"id":"487349",
"name":"Pooja Bhaumik",
"score" : 1000
}
序列化和反序列化
序列化只是意味着将数据(可能在对象中)写为字符串,而反序列化则与此相反。它获取原始数据并重建对象模型。即可以通过对象来得到其中的数据。
Json解析
1.内连序列化
通过调用JSON.decode方法来解码JSON,使用JSON字符串作为参数,例:
//这里的MAP中,第一个参数指key的类型是String,但是key值对应得值可能有int,String,List等,所以为动态
Map<String,dynamic> student = JSON.decode(json);
由于返回的数据类型为dynamic,所以只有运行的时候才知道类型有没有出错。通过这种方法,我们失去了大部分静态类型语言特性:类型安全、自动补全和最重要的编译时异常。这样一来,我们的代码可能会变得非常容易出错。
对于简单的Json数据用这种方法较为简单,如官方例子:
{
"name": "John Smith",
"email": "john@example.com"
}
2.在模型类中序列化 (规则2:对于嵌套结构,首先创建类和构造函数,然后从底层添加工厂方法。)此处为反序列化,因为没有用toJson
(官方方法为先反序列得到数据类型,再通过toJson进行序列化,这里不用toJson)
通过创建一个模型类(model)来方便在编译时知道类型,提醒错误。例:
//主要是写banner1中的fromJson方法,实现反序列化的目的并且
//其中banner1中有3个Key,其中两个为String,一个为Datas数组(所以还需要创建一个Datas类,再写其中的fromjson方法
//用Banner1是防止与关键字Banner重名
class Banner1 {
//变量名需要是Json数据中的Key值,Datas类型自己定义,用来序列化data内部的键,
//否则再外层解析时只能解析到dunamic
final List<Datas> data;
final int errorCode;
final String errorMsg;
Banner1({this.data,this.errorCode,this.errorMsg});
//fromJson
//当不是需要一个对象时候,可以用factory
factory Banner1.fromJson(Map<String,dynamic> parsedJson){
//由于Json数据中data是一个list数组,所以需要创建一个list分配给data
//不能用data:paresedJson['data']
//(会提示type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'data')
//同时也不能用data:Datas.fromJson(parsedjson['data'])
//由于data是list<Datas>类型,而不是Datas对象
var list = parsedJson['data'] as List;
//需要创建一个dataLsit然后分配给data
//遍历dataList列表,将每一个映射都调用fromJson,再将其存储到dataList中
List<Datas> dataList = list.map((i) => Datas.fromJson(i)).toList();
return Banner1(
errorCode: parsedJson['errorCode'],
errorMsg: parsedJson['errorMsg'],
data: dataList
);
}
}
class Datas{
final String desc;
final int id;
final String imagePath;
final int isVisible;
final int order;
final String title;
final int type;
final String url;
Datas({this.desc, this.id, this.imagePath, this.isVisible, this.order,
this.title, this.type, this.url});
factory Datas.fromJson(Map<String,dynamic> parsedJson){
return Datas(
desc: parsedJson['desc'],
id: parsedJson['id'],
imagePath: parsedJson['imagePath'],
isVisible: parsedJson['isVisible'],
order: parsedJson['order'],
title: parsedJson['title'],
type: parsedJson['type'],
url: parsedJson['url']
);
}
}
加载Json数据
//采用异步操作
Future loadBanner(int index) async {
//所需要的数据
String imagePath;
//获取Json格式字符串
String jsonBanner = await _loadBannerJson();
//解析Json
final jsonResponse = json.decode(jsonBanner);
//进行反序列化,得到banner1对象
Banner1 banner = new Banner1.fromJson(jsonResponse);
//得到所需数据
imagePath = banner.data[index].imagePath;
}
参考
https://www.jianshu.com/p/4a11d68d3239
https://medium.com/flutter-community/parsing-complex-json-in-flutter-747c46655f51 (原文)