json_serializable是flutter开发中比较流行的插件了.由于dart禁止运行时反射,没有不能动态获取类型来创建对象.所以在解析json的时候比较麻烦
这里介绍最通用的方法
json例子:
{
"code": 200001,
"msg": "success",
"data": {
"mydata": {
"name": "张三",
"age": "21",
"tel": "1539324****",
"balance": "100"
}
}
}
使用genericArgumentFactories
首先genericArgumentFactories参数设置为true,就开启了框架默认的json解析方式
@JsonSerializable(genericArgumentFactories: true)
class BaseJson<T> {
int? code;
String? msg;
T? data;
}
可以看到生成的解析方法多了一个函数参数`T Function(Object? json) fromJsonT,`并且把我们的泛型data字段,当做参数传入.所以我们解析的时候,只需要把泛型的fromJson调用一下就行了
BaseJson<T> _$BaseJsonFromJson<T>(
Map<String, dynamic> json,
T Function(Object? json) fromJsonT,
) =>
BaseJson<T>()
..code = json['code'] as int?
..msg = json['msg'] as String?
..data = _$nullableGenericFromJson(json['data'], fromJsonT);
Map<String, dynamic> _$BaseJsonToJson<T>(
BaseJson<T> instance,
Object? Function(T value) toJsonT,
) =>
<String, dynamic>{
'code': instance.code,
'msg': instance.msg,
'data': _$nullableGenericToJson(instance.data, toJsonT),
};
T? _$nullableGenericFromJson<T>(
Object? input,
T Function(Object? json) fromJson,
) =>
input == null ? null : fromJson(input);
对应上面的json,写好3个model.
@JsonSerializable(genericArgumentFactories: true)
class BaseJson<T> {
int? code;
String? msg;
T? data;
BaseJson();
factory BaseJson.fromJson(
Map<String, dynamic> json, T Function(dynamic json) fromJsonT) =>
_$BaseJsonFromJson(json, fromJsonT);
Map<String, dynamic> toJson(
Object? Function(T value) toJsonT,
) =>
_$BaseJsonToJson(this, toJsonT);
}
@JsonSerializable(genericArgumentFactories: true)
class Data1<T> {
T? mydata;
Data1();
factory Data1.fromJson(
Map<String, dynamic> json, T Function(dynamic json) fromJsonT) =>
_$Data1FromJson(json, fromJsonT);
Map<String, dynamic> toJson(
Object? Function(T value) toJsonT,
) =>
_$Data1ToJson(this, toJsonT);
}
@JsonSerializable()
class MyData {
String? name;
String? age;
String? tel;
String? balance;
MyData();
factory MyData.fromJson(Map<String, dynamic> json) => _$MyDataFromJson(json);
Map<String, dynamic> toJson() => _$MyDataToJson(this);
}
带有泛型的 fromJson跟toJson与普通的Json转换有所不同
而且`T Function(Object? json) fromJsonT,`自动生成的函数参数类型是Object?,我们使用的时候要转类型,为了方便直接改成dynamic
测试一下
var jsonData =
"{\"code\": 200001,\"msg\": \"success\",\"data\": {\"mydata\": {\"name\": \"张三\",\"age\": \"21\",\"tel\": \"1539324****\",\"balance\": \"100\"}}}";
//JSON字符串解析成map
var jsonMap = json.decoder.convert(jsonData);
//map转model
BaseJson<Data1<MyData>> baseJson = BaseJson.fromJson(jsonMap, (json) {
return Data1.fromJson(json, (json) {
return MyData.fromJson(json);
});
});
//model转jsonMap
print(baseJson.toJson((value) => value.toJson((value) => value.toJson())));
把data改成list的话再试一下
{
"code": 200001,
"msg": "success",
"data": [
{
"name": "张三",
"age": "21",
"tel": "1539324****",
"balance": "100"
}
]
}
var jsonData =
"{\"code\": 200001,\"msg\": \"success\",\"data\": [{\"name\":\"张三\",\"age\": \"21\",\"tel\": \"1539324****\",\"balance\": \"100\"}]}";
var jsonMap = json.decoder.convert(jsonData);
BaseJson<List<MyData>> baseJson = BaseJson.fromJson(jsonMap, (json) {
//判断json是不是数组类型
if (json is List) {
//map操作符遍历生产model
return json.map((e) => MyData.fromJson(e)).toList();
}
//其它情况返回个空数组
return [];
});
print(baseJson.toJson((value) => value.map((value) => value.toJson()).toList()));