flutter/Dart中解析后端传来的json数据,包含分页json、对象json、数组json

提前声明:本人一个被毕设折磨的学生,也是初学flutter,并不确定对于解析json这种功能有没有更简洁、更优雅的实现方式,但是我的这种方式确实能用,但也只能说是functional。😅

需求是这样的,后端定义了Result类对象作为统一返回的结果,
但是data部分的内容是不固定的,可能是分页对象,可能是数组,可能是某一个类对象,所以接收到的json就有三种形式,我想要的就是提取出data并解析成指定的类型。可惜最终并没有实现一个类就能统一处理三种返回类型,而是针对三种类型写了三个类进行解析处理。先从最简单的对象解析开始:
(1)对象
在这里插入图片描述
step1:先生成对象的实体类,我用的是quicktype:https://app.quicktype.io/
把json复制到左边,右边就是实体类:
在这里插入图片描述
然后,新建一个文件名为ResultObj.dart , 意为解析对象专用的类。

class ResultObj<T> {
  String? msg;
  int? code;
  T? data;

  ResultObj({
    this.msg,
    this.code,
    this.data,
  });

  ResultObj.fromJson(Map<String, dynamic> json ,T Function(dynamic json) fromJsonT) {
    // _$ResultObjFromJson(json, data);
    msg=json['msg'];
    code = json['code'];
    data = fromJsonT(json['data'] as Map<String,dynamic>);
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = Map<String, dynamic>();
    data['code'] = this.code;
    data['msg'] = this.msg;
    data['data'] = this.data;
    return data;
  }
}

其中的T Function(dynamic json) fromJsonT 就是目标实体类的fromJson方法(此例中就是NewsType中的fromJson方法)
直接看看具体怎么使用就懂了,注意下面代码中,fromJson接收两个参数:
第一个是 response.data 变量,也就是就是网络请求后得到的Map<String, dynamic>类型的对象;
第二个参数是一个函数,就是告诉ResultObj用NewsType类中的fromJson方法进行处理。json就是一个形式变量,叫什么无所谓。
另外,注意ResultObj中定义了泛型T,但是具体用的时候填不填泛型无所谓,因为已经指明了是NewsType.fromJson(json)
使用方法:

var resultObj = ResultObj.fromJson(response.data, (json) => NewsType.fromJson(json));
NewsType newsType = resultObj.data;

(2)数组

处理数组其实就是在上面解析对象的基础上加了一个遍历,即:对数组中的每一个对象都调用一下传入的fromJsonT方法。
假设收到的json如下:
在这里插入图片描述
对应的用于解析数组的类,命名为ResultList:

class ResultList<T> {
   String? msg;
   int? code;
   List<T>? data;

  ResultList({
    this.msg,
    this.code,
    this.data,
  });

   ResultList.fromJson(Map<String, dynamic> json,T Function(dynamic json) fromJsonT) {
        msg=json['msg'];
        code=json['code'];
        data=(json['data'] as List<dynamic>).map((e) => fromJsonT(e)).toList();
  }
}

重点就是其中的map((e) => fromJsonT(e)).toList();遍历了数组,把每个元素都用fromJsonT变成了NewsType对象。
使用上还是一样的:


var resultList = ResultList.fromJson(response.data, (json) => NewsType.fromJson(json));
List<NewsType> list = resultList.data!;

(3)分页对象

假设json长这样:
在这里插入图片描述
目标是提取出分页对象result,
通过result.msg即可获取到 “success”;
通过result.data.totalCount就可以知道总条目数 13;
通过result.data.list就可以获得 List< NewsType> 对象…
对应的解析用的类命名为ResultPage.dart:


class ResultPage<T> {
  String? msg;
  int? code;
  Data<T>? data;

  ResultPage({
    this.msg,
    this.code,
    this.data,
  });

  ResultPage.fromJson(Map<String, dynamic> json,T Function(dynamic json) fromJsonT) {
    msg=json['msg'];
    code=json['code'];
    data=Data.fromJson(json['data'], (json) => fromJsonT(json));
  }

  // Map<String, dynamic> toJson() => _$ResultPageToJson(this);
}

()
class Data<T> {
  int? totalCount;
  int? pageSize;
  int? totalPage;
  int? currentPage;
  List<T>? list;

  Data({
    this.totalCount,
    this.pageSize,
    this.totalPage,
    this.currentPage,
    this.list,
  });

  Data.fromJson(Map<String, dynamic> json,T Function(dynamic json) fromJsonT) {
    totalCount=json['totalCount'];
    pageSize=json['pageSize'];
    totalPage=json['totalPage'];
    currentPage=json['currentPage'];
    list=(json['list'] as List<dynamic>).map((e) => fromJsonT(e)).toList();

  }

  // Map<String, dynamic> toJson() => _$DataToJson(this);
}

这个稍微复杂点,因为data里套了一个page对象,page对象里套了个数组,但本质上就是上面两种情况的组合。泛型T从ResultPage传给了Data类。
实际使用:

    ResultPage<News> result = ResultPage<News>.fromJson(response.data, (json) => News.fromJson(json));
	var list = result.data!.list as List<News>

其实写完了再来看,好像也没有很复杂的样子。。。。😅

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值