Flutter 自动化Json转Model的实现

一、准备数据源

// mockData.dart
abstract class JsonString{
  static final String mockdata = ''' {
  "by" : "dhouston",
  "descendants" : 71,
  "id" : 8863,
  "kids" : [ 8952, 9224, 8917, 8884, 8887, 8943, 8869, 8958, 9005, 9671, 8940, 9067, 8908, 9055, 8865, 8881, 8872, 8873, 8955, 10403, 8903, 8928, 9125, 8998, 8901, 8902, 8907, 8894, 8878, 8870, 8980, 8934, 8876 ],
  "score" : 111,
  "time" : 1175714200,
  "title" : "My YC app: Dropbox - Throw away your USB drive",
  "type" : "story",
  "url" : "http://www.getdropbox.com/u/2/screencast.html"
}''';
}

二、添加第三方库

 dependencies:
 flutter:
    sdk: flutter
 json_serializable: ^3.2.0
 json_annotation: ^3.0.0
 build_runner: ^1.6.6

dev_dependencies:
  flutter_test:
    sdk: flutter

添加这json_serializable库 和json_annotationbuild_runner两个依赖,这个三个库可在https://pub.dev 中搜索最新的版本。

三、创建Model

// peesonModel.dart
class Data{
  final String by;
  final int descendants;
  final int id;
  final List kids;
  final int score;
  final int time;
  final String title;
  final String type;
  final String url;

  Data({this.by, this.descendants, this.id, this.kids, this.score, this.time,
    this.title, this.type, this.url});
}

四、自动化配置

// peesonModel.dart
import 'package:json_annotation/json_annotation.dart';

part 'peesonModel.g.dart'; // 我的文件名是peesonModel.dart

@JsonSerializable()
class Data {
  final String by;
  final int descendants;
  final int id;
  final List kids;
  final int score;
  final int time;
  final String title;
  final String type;
  @JsonKey(nullable: false)
  final String url;

  Data({this.by, this.descendants, this.id, this.kids, this.score, this.time,
    this.title, this.type, this.url});

五、生成Json解析文件
使用JsonSerializable生成代码的话必须要在需要生成代码的实体类前添加注解@JsonSerializable(),而要使用这个注解我们必须引入json_annotation/json_annotation.dart这个包。

build_runnerdart团队提供的一个生成dart代码文件的外部包,用于自动化构建Json解析文件。

我们在当前项目的目录下运行如下命令:
flutter packages pub run build_runner build

生成peesonModel.g.dart文件

这个peesonModel.g.dartbuild_runner根据JsonSerializable生成的json解析文件。
我们来看看这个生成的dart文件

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'peesonModel.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

Data _$DataFromJson(Map json) {
  return Data(
    by: json['by'] as String,
    descendants: json['descendants'] as int,
    id: json['id'] as int,
    kids: (json['kids'] as List)?.map((e) => e as int)?.toList(),
    score: json['score'] as int,
    time: json['time'] as int,
    title: json['title'] as String,
    type: json['type'] as String,
    url: json['url'] as String,
  );
}

Map _$DataToJson(Data instance) => {
      'by': instance.by,
      'descendants': instance.descendants,
      'id': instance.id,
      'kids': instance.kids,
      'score': instance.score,
      'time': instance.time,
      'title': instance.title,
      'type': instance.type,
      'url': instance.url,
    };

_$DataFromJson:它接收了一个map:Map,并将这个Map里的值映射为我们所需要的实体类对象。我们就可以使用这个方法,将存有json数据的map转化为我们需要的实体类对象。
_$DataToJson:将调用此方法的对象直接根据字段映射成Map。

六、重新构建peesonModel.dar文件中Data类

import 'package:json_annotation/json_annotation.dart';
part 'peesonModel.g.dart';

@JsonSerializable()
class Data {
  final String by;
  final int descendants;
  final int id;
  final List kids;
  final int score;
  final int time;
  final String title;
  final String type;
  final String url;

  // 声明一个和类名相同的函数,来作为类的构造函数。
  // this关键字指向了当前类的实例, 上面的代码可以简化为:
  Data(
      {this.by,
      this.descendants,
      this.id,
      this.kids,
      this.score,
      this.time,
      this.title,
      this.type,
      this.url});

  // 使用命名构造函数从另一类或现有的数据中快速实现构造函数。
  // 一个User.fromJson 构造函数, 用于从一个map构造出一个 User实例 map structure
  factory Data.fromJson(Map json) => _$DataFromJson(json);

  // 一个toJson 方法, 将 User 实例转化为一个map.
  Map toJson() => _$DataToJson(this);
}
/**
 * _$DataFromJson:它接收了一个map:Map,并将这个Map里的值映射为我们所需要的实体类对象。
 * 我们就可以使用这个方法,将存有json数据的map转化为我们需要的实体类对象。
 *
 * _$DataToJson:将调用此方法的对象直接根据字段映射成Map。
 *
 * 而这两个都是私有方法,part让两个文件共享作用域与命名空间,所以我们需要将生成的方法暴露给外部。
 * 然后我们再回到实体类中将 添加fromJson 和 toJson方法。
 * */

七、业务场景使用

import 'peesonModel.dart';
import 'mockData.dart';
import 'dart:convert';

// json转成Map ,依赖库dart:convert, Map user = json.decode(json);
Map dataMap = json.decode(JsonString.mockdata);
// Map转成Model
Data data1 = Data.fromJson(dataMap);

// Model转成Map 
Map dataMap1 = data1.toJson();

至此,我们已经实现了 json转成Map, Json 转 ModelModel转成Map

你可能感兴趣的:(Flutter 自动化Json转Model的实现)