• Flutter之Json序列化


    前言

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

    框架官方地址:json_serializable

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

    1. dependencies:
    2. json_annotation: ^4.8.1
    3. dev_dependencies:
    4. build_runner: ^2.3.3
    5. json_serializable: ^6.6.0

    二、使用过程

    数据源:

    1. {
    2. "id": 1,
    3. "name": "John",
    4. "email": "john@example.com",
    5. "phone_numbers": [
    6. {
    7. "type": "home",
    8. "number": "1234567890"
    9. },
    10. {
    11. "type": "work",
    12. "number": "0987654321"
    13. }
    14. ]
    15. }

    创建数据模型:

    1. // 引入依赖
    2. import 'package:json_annotation/json_annotation.dart';
    3. // 指定此类的代码生成文件(格式:part '类名.g.dart';)
    4. part 'Person.g.dart';
    5. // 添加序列化标注
    6. @JsonSerializable()
    7. class Person {
    8. int id;
    9. String name;
    10. String email;
    11. // 使用别名
    12. @JsonKey(name: "phone_numbers")
    13. List<PhoneNumber> phoneNumbers;
    14. Person(this.id, this.name, this.email, this.phoneNumbers);
    15. // 添加反序列化方法(格式:factory 类名.fromJson(Map<String, dynamic> json) => _$类名FromJson(json);)
    16. factory Person.fromJson(Map<String,dynamic> json) => _$PersonFromJson(json);
    17. // 添加序列化方法(格式:Map<String, dynamic> toJson() => _$类名ToJson(this);)
    18. Map<String,dynamic> toJson() => _$PersonToJson(this);
    19. }
    20. @JsonSerializable()
    21. class PhoneNumber {
    22. String type;
    23. String number;
    24. PhoneNumber(this.type, this.number);
    25. factory PhoneNumber.fromJson(Map<String,dynamic> json) => _$PhoneNumberFromJson(json);
    26. Map<String,dynamic> toJson() => _$PhoneNumberToJson(this);
    27. }

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

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

    flutter pub run build_runner build

    命令生成过程:

    1. PS D:\AndroidStudioProjects\github_client_app> flutter pub run build_runner build
    2. Deprecated. Use `dart run` instead.
    3. Building package executable... (5.9s)
    4. Built build_runner:build_runner.
    5. [INFO] Generating build script completed, took 252ms
    6. [INFO] Reading cached asset graph completed, took 73ms
    7. [INFO] Checking for updates since last build completed, took 685ms
    8. [INFO] Running build completed, took 19.0s
    9. [INFO] Caching finalized dependency graph completed, took 87ms
    10. [INFO] Succeeded after 19.1s with 602 outputs (606 actions)
    11. PS D:\AndroidStudioProjects\github_client_app> flutter pub run build_runner build
    12. Deprecated. Use `dart run` instead.
    13. [INFO] Generating build script completed, took 252ms
    14. [INFO] Reading cached asset graph completed, took 193ms
    15. [INFO] Checking for updates since last build completed, took 683ms
    16. [INFO] Running build completed, took 10.1s
    17. [INFO] Caching finalized dependency graph completed, took 86ms
    18. [INFO] Succeeded after 10.2s with 189 outputs (193 actions)

    查看Person.g.dart

    1. // GENERATED CODE - DO NOT MODIFY BY HAND
    2. part of 'Person.dart';
    3. // **************************************************************************
    4. // JsonSerializableGenerator
    5. // **************************************************************************
    6. Person _$PersonFromJson(Map<String, dynamic> json) => Person(
    7. json['id'] as int,
    8. json['name'] as String,
    9. json['email'] as String,
    10. (json['phone_numbers'] as List<dynamic>)
    11. .map((e) => PhoneNumber.fromJson(e as Map<String, dynamic>))
    12. .toList(),
    13. );
    14. Map<String, dynamic> _$PersonToJson(Person instance) => <String, dynamic>{
    15. 'id': instance.id,
    16. 'name': instance.name,
    17. 'email': instance.email,
    18. 'phone_numbers': instance.phoneNumbers,
    19. };
    20. PhoneNumber _$PhoneNumberFromJson(Map<String, dynamic> json) => PhoneNumber(
    21. json['type'] as String,
    22. json['number'] as String,
    23. );
    24. Map<String, dynamic> _$PhoneNumberToJson(PhoneNumber instance) =>
    25. <String, dynamic>{
    26. 'type': instance.type,
    27. 'number': instance.number,
    28. };

    使用示例:

    1. void jsonTest() {
    2. final json = '''
    3. {
    4. "id": 1,
    5. "name": "John",
    6. "email": "john@example.com",
    7. "phone_numbers": [
    8. {
    9. "type": "home",
    10. "number": "1234567890"
    11. },
    12. {
    13. "type": "work",
    14. "number": "0987654321"
    15. }
    16. ]
    17. }
    18. ''';
    19. final person = Person.fromJson(jsonDecode(json));
    20. print("steve:${person.name}");
    21. final jsonEncoded = jsonEncode(person.toJson());
    22. print("steve:$jsonEncoded");
    23. }

    打印的日志:

    1. I/flutter ( 1781): steve:John
    2. 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

  • 相关阅读:
    MySQL向自增列插入0失败问题
    一文理解Cookie、Session
    react-router-dom 实用技巧及3种传参方式
    【黄啊码】MySQL入门—5、掌握这些数据筛选技能比你学python还有用-2
    Chrome DOM断点之实现源码追溯
    项目实战:一个由多线程引起的线程安全问题(附:解决方案)
    人体关键点识别易语言代码
    强制解决Java参数乱码问题
    abortControllerMap: Map<string, AbortController>
    C++11补充:智能指针如std::unique_ptr如何添加自定义的deleter
  • 原文地址:https://blog.csdn.net/Steve_XiaoHai/article/details/134312925