Flutter之Json序列化

前言

使用 json_annotation 框架实现json字符串序列化和反序列化

框架官方地址:json_serializable

一、引入依赖:在pubspec.yaml中添加

复制代码
dependencies:
    json_annotation: ^4.8.1


dev_dependencies:
  build_runner: ^2.3.3
  json_serializable: ^6.6.0

二、使用过程

数据源:

复制代码
{
  "id": 1,
  "name": "John",
  "email": "john@example.com",
  "phone_numbers": [
    {
      "type": "home",
      "number": "1234567890"
    },
    {
      "type": "work",
      "number": "0987654321"
    }
  ]
}

创建数据模型:

复制代码
// 引入依赖
import 'package:json_annotation/json_annotation.dart';

// 指定此类的代码生成文件(格式:part '类名.g.dart';)
part 'Person.g.dart';

// 添加序列化标注
@JsonSerializable()
class Person {
  int id;
  String name;
  String email;
  // 使用别名
  @JsonKey(name: "phone_numbers")
  List<PhoneNumber> phoneNumbers;

  Person(this.id, this.name, this.email, this.phoneNumbers);
  // 添加反序列化方法(格式:factory 类名.fromJson(Map<String, dynamic> json) => _$类名FromJson(json);)
  factory Person.fromJson(Map<String,dynamic> json) => _$PersonFromJson(json);
  // 添加序列化方法(格式:Map<String, dynamic> toJson() => _$类名ToJson(this);)
  Map<String,dynamic> toJson() => _$PersonToJson(this);
}

@JsonSerializable()
class PhoneNumber {
  String type;
  String number;

  PhoneNumber(this.type, this.number);
  factory PhoneNumber.fromJson(Map<String,dynamic> json) => _$PhoneNumberFromJson(json);
  Map<String,dynamic> toJson() => _$PhoneNumberToJson(this);
}

使用命令生成对应的.g.dart内容

在android studio的Terminal终端使用如下命令:

复制代码
flutter pub run build_runner build

命令生成过程:

复制代码
PS D:\AndroidStudioProjects\github_client_app> flutter pub run build_runner build
Deprecated. Use `dart run` instead.
Building package executable... (5.9s)
Built build_runner:build_runner.
[INFO] Generating build script completed, took 252ms
[INFO] Reading cached asset graph completed, took 73ms
[INFO] Checking for updates since last build completed, took 685ms
[INFO] Running build completed, took 19.0s
[INFO] Caching finalized dependency graph completed, took 87ms
[INFO] Succeeded after 19.1s with 602 outputs (606 actions)
PS D:\AndroidStudioProjects\github_client_app> flutter pub run build_runner build
Deprecated. Use `dart run` instead.
[INFO] Generating build script completed, took 252ms
[INFO] Reading cached asset graph completed, took 193ms
[INFO] Checking for updates since last build completed, took 683ms
[INFO] Running build completed, took 10.1s
[INFO] Caching finalized dependency graph completed, took 86ms
[INFO] Succeeded after 10.2s with 189 outputs (193 actions)

查看Person.g.dart

复制代码
// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'Person.dart';

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

Person _$PersonFromJson(Map<String, dynamic> json) => Person(
      json['id'] as int,
      json['name'] as String,
      json['email'] as String,
      (json['phone_numbers'] as List<dynamic>)
          .map((e) => PhoneNumber.fromJson(e as Map<String, dynamic>))
          .toList(),
    );

Map<String, dynamic> _$PersonToJson(Person instance) => <String, dynamic>{
      'id': instance.id,
      'name': instance.name,
      'email': instance.email,
      'phone_numbers': instance.phoneNumbers,
    };

PhoneNumber _$PhoneNumberFromJson(Map<String, dynamic> json) => PhoneNumber(
      json['type'] as String,
      json['number'] as String,
    );

Map<String, dynamic> _$PhoneNumberToJson(PhoneNumber instance) =>
    <String, dynamic>{
      'type': instance.type,
      'number': instance.number,
    };

使用示例:

复制代码
void jsonTest() {
    final json = '''
{
  "id": 1,
  "name": "John",
  "email": "john@example.com",
  "phone_numbers": [
    {
      "type": "home",
      "number": "1234567890"
    },
    {
      "type": "work",
      "number": "0987654321"
    }
  ]
}
''';
    final person = Person.fromJson(jsonDecode(json));
    print("steve:${person.name}");
    final jsonEncoded = jsonEncode(person.toJson());
    print("steve:$jsonEncoded");
  }

打印的日志:

复制代码
I/flutter ( 1781): steve:John
I/flutter ( 1781): steve:{"id":1,"name":"John","email":"john@example.com","phone_numbers":[{"type":"home","number":"1234567890"},{"type":"work","number":"0987654321"}]}

补充:

jsonKey

  • nullable:默认为true,表示该字段可为null
  • defaultValue:如果源JSON不包含该key或该keyvaluenull,提供一个默认值。
  • name:别名,若为null则默认为字段名。
  • required:默认为false,若为真会检查JSON是否包含该key,若没有则抛出异常(keynull也是有效的)。

生成.g.dart文件

一次性构建
复制代码
flutter packages pub run build_runner build
删除后重新构建
复制代码
flutter packages pub run build_runner build --delete-conflicting-outputs
自动为后续创建的数据模型创建
复制代码
flutter packages pub run build_runner watch
相关推荐
2501_944448007 分钟前
Flutter for OpenHarmony 衣橱管家App实战 - 智能推荐实现
flutter
菜鸟小芯15 分钟前
【开源鸿蒙跨平台开发先锋训练营】DAY8~DAY13 底部选项卡&我的页面功能实现
flutter·harmonyos
灰灰勇闯IT17 分钟前
Flutter for OpenHarmony:悬浮按钮(FloatingActionButton)最佳实践 —— 强化核心操作,提升用户效率
flutter·华为·交互
雨季66626 分钟前
Flutter 三端应用实战:OpenHarmony “心流之泉”——在碎片洪流中,为你筑一眼专注的清泉
开发语言·前端·flutter·交互
一起养小猫1 小时前
Flutter for OpenHarmony 进阶:表达式解析算法与计算器核心实现
算法·flutter·harmonyos
不爱吃糖的程序媛2 小时前
Flutter 三方库鸿蒙(OHOS)适配分析流程
flutter·华为·harmonyos
mocoding2 小时前
我这样用鸿蒙化Flutter三方库file_selector实现单图片和多图片选择
flutter·华为·harmonyos
牛马1113 小时前
flutter Riverpod 中的 overrideWith
android·java·flutter
牛马1113 小时前
flutter riverpod AsyncNotifier 和 Notifier
flutter
不爱吃糖的程序媛3 小时前
如何判断Flutter三方库是否需要OHOS适配开发?附完整适配指导
flutter·华为·harmonyos