Flutter json_serializable解析json泛型常用方法(genericArgumentFactories)

 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()));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值