11.7 Json To Dart Model

实际开发中该接口返回的数据往往是JSON或者XML等,入职前的请求Github中返回的是Json格式字符串,为了方便我们在代码中操作JSON,首先要将JSON转成Dart对象,这个可以通过dart:convert中内置的JSON解码器来实现,转成List或者Map,就可以查找其中的值。

String jsonStr = '[{"name":"Jack Ma"},{"name":"QiangDong liu"}]';
List items = json.decode(jsonStr);
print(items[0]['name']); // Jack Ma

通过json.decode()将JSON字符串转成序列化的List/Map比较简单,对于项目变大,手动写序列化逻辑比较复杂,当字段名字稍微复杂点,可能名字会打错导致运行出错,这是我们不想看到的。

其实,这问题在很多平台开发中都会遇到,而也早就有了解决 方法,Json Model 化,具体做法是通过预定义一些与JSON结构对应的Model类,然后在请求到数据再动态创建model类的实例。这样子在开发阶段使用的model类的实例,而不是List和Map,这样子访问内部属性时就不会拼错。

例如:

class User {
  final String name;
  final String email;

  User(this.name, this.email);

  User.fromJson(Map<String, dynamic> json)
      : name = json['name'],
        email = json['email'];

  Map<String, dynamic> toJson() =>
    <String, dynamic>{
      'name': name,
      'email': email,
    };
}

现在,序列化逻辑移动到了模型内部,采用这种方式,我们非常容易的反序列化了。

Map userMap = json.decode(json);
var user = new User.fromJson(userMap);

print('Howdy, ${user.name}!');
print('We sent the verification link to ${user.email}.');

自动生成Model

我们介绍下官方库json_serializable

导入:

 json_annotation: ^*.0.0

然后运行pub packages get.

以json_serializable的方式创建model类

我们示例一下用json_serializable如何将我们的user类转换为一个json_serializable.

user.dart

import 'package:json_annotation/json_annotation.dart';

// user.g.dart 将在我们运行生成命令后自动生成
part 'user.g.dart';

///这个标注是告诉生成器,这个类是需要生成Model类的
@JsonSerializable()

class User{
  User(this.name, this.email);

  String name;
  String email;
  //不同的类使用不同的mixin即可
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);  
}

然后在根目录运行代码生成器

flutter packages pub run build_runner build

这触发了一次构建,我们可以在需要我们的model生成json序列化代码,他通过我们的源文件生成model类的源文件,来生成对应的.g.dart文件,一个好的建议是将所有model类放在已单独的目录下,然后再改目录下执行命令。

持续生成

按照上面的每次写一个model都是需要单独运行一个代码生成器,可以用下边的 命令来启动观察者,

flutter packages pub run build_runner watch

使用FlutterJsonBeanFactory

安装插件

安装插件并重启,在mac电脑Androidstudio 中快捷键'com+,'打开界面,安装并重启。

然后就可以使用插件了。准备好需要转成model的格式的字符串。

代码使用

字符串转model

String jsonStr = '{"list":[{"name":"Jack Ma"},{"name":"QiangDong liu"}]}';
UserEntity list = JsonConvert.fromJsonAsT<UserEntity>(json.decode(jsonStr));

dio 返回结果直接转model

(_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
    (client) {
  client.findProxy = (uri) {
    return "PROXY localhost:1088";
  };

};
Response res = await _dio.get('https://api.github.com/users/ifgyong/repos');
List<dynamic> list = res.data;
List<GitModel> gitList = [];
if (res.data is List) {
  (res.data as List).forEach((element) {
    GitModel modl = JsonConvert.fromJsonAsT<GitModel>(element);
    gitList.add(modl);
  });
  print('${gitList.length}'); // 输出 30
}

results matching ""

    No results matching ""