Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flutter 项目中使用 json_serializable 序列化和反序列化 Json #209

Open
bingoogolapple opened this issue Jan 9, 2019 · 4 comments
Labels

Comments

@bingoogolapple
Copy link
Owner

bingoogolapple commented Jan 9, 2019

接入 json_serializable

dependencies:
  json_annotation: ^2.0.0

dev_dependencies:
  build_runner: ^1.1.2
  json_serializable: ^2.0.1
  • 新建 xxx.dart 文件,导入 json_annotation 包
import 'package:json_annotation/json_annotation.dart';
  • 并将即将生成的 xxx.g.dart 文件作为 xxx.dart 文件的 part。这里配置后因为没生成,编辑器会提示错误,但是必须先配置 part,否则后面不会自动生成 xxx.g.dart 文件
part 'xxx.g.dart';
  • 在类上添加 JsonSerializable 注解
    image
  • Dart 项目执行以下命令生成 xxx.g.dart 文件
pub run build_runner build
  • Flutter 项目执行以下命令生成 xxx.g.dart 文件。可以配置别名方便后续使用「可以配置别名 alias genjson="flutter packages pub run build_runner build"」
flutter packages pub run build_runner build
  • 绑定序列化和反序列化方法
    image
@bingoogolapple
Copy link
Owner Author

bingoogolapple commented Jan 9, 2019

JsonKey 注解说明

1、name「序列化和反序列化时的名称」

  • 默认为 null,使用字段名称
  • 不为空时使用 name 指定的值

2、nullable「序列化和反序列化时值是否可以为 null」

  • 默认为 true,反序列化时不为 null 才转换,序列化时会使用 ?判空后转换
  • 设置为 false 时,反序列化时不会判空直接转换,序列化时不会使用 ?判空直接转换
    image
    image
    image

3、includeIfNull「序列化时」如果属性值为 null,是否添加该 key

  • 默认为 true,即使属性值为 null 也会添加到 Json 中
  • 指定为 false 时,会判断属性值是否为 null,如果为 null 则不添加到 Json 中
    image
    image

4、ignore「序列化和反序列化时」是否忽略该 key

  • 默认为 null,为 null 或 false 时,不会忽略
  • 指定为 true 时,序列化和反序列化时都会忽略

5、required「反序列化时」是否必须存在该 key

  • 默认为 false,可以不存在该 key
  • 指定为 true 时,必须存在该 key,生成的文件的 _$XxxFromJson 方法中会校验
    image
    image
    image

6、disallowNullValue「反序列化时」不允许值为 null 值。和 includeIfNull 不能同时为 true

  • 默认为 false
  • 设置为 true 时,生成的文件的 _$XxxFromJson 方法中会校验,如果存在该 key 且值等于 null 时会抛异常
    image

7、defaultValue「反序列化时」不包含 key 或值为 null 时的默认值

  • 不指定时取不到值的话默认为 null
    image

8、fromJson「反序列化时自定义转换方法」,toJson「序列化时自定义转换方法」,需要时顶级方法或静态方法,可以不同时指定,但建议同时指定

image
image
image

@bingoogolapple bingoogolapple changed the title json_serializable Flutter 项目中使用 json_serializable 序列化和反序列化 Json Jan 9, 2019
@bingoogolapple
Copy link
Owner Author

bingoogolapple commented Jan 9, 2019

JsonSerializable 注解说明

1、includeIfNull,同 JsonKey 注解的 includeIfNull,应用于整个类的所有属性,优先级低于单独为 Json 指定的 includeIfNull 值

2、nullable,同 JsonKey 注解的 nullable,应用于整个类的所有属性,优先级低于单独为 Json 指定的 nullable 值

3、TODO

@bingoogolapple
Copy link
Owner Author

bingoogolapple commented Jan 9, 2019

通过实现 JsonConverter 接口,编写自定义注解来实现自定义类型转换

import 'package:json_annotation/json_annotation.dart';

part 'json_converter_example.g.dart';

@JsonSerializable()
class GenericCollection<T> {
  @JsonKey(name: 'page')
  final int page;

  @JsonKey(name: 'total_results')
  final int totalResults;

  @JsonKey(name: 'total_pages')
  final int totalPages;

  @JsonKey(name: 'results')
  @_Converter()
  final List<T> results;

  GenericCollection({this.page, this.totalResults, this.totalPages, this.results});

  factory GenericCollection.fromJson(Map<String, dynamic> json) => _$GenericCollectionFromJson<T>(json);

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

class _Converter<T> implements JsonConverter<T, Object> {
  const _Converter();

  @override
  T fromJson(Object json) {
    if (json is Map<String, dynamic> && json.containsKey('name') && json.containsKey('size')) {
      return CustomResult.fromJson(json) as T;
    }
    // 只有在 json 是 JSON 基本类型时才有效:num,String,bool,null 等,强制类型转换为 T
    return json as T;
  }

  @override
  Object toJson(T object) {
    // 只有在 object 是 JSON 基本类型时才有效:num,String,bool,null 等,或有 toJson 方法
    return object;
  }
}

@JsonSerializable()
class CustomResult {
  final String name;
  final int size;

  CustomResult(this.name, this.size);

  factory CustomResult.fromJson(Map<String, dynamic> json) => _$CustomResultFromJson(json);

  Map<String, dynamic> toJson() => _$CustomResultToJson(this);

  @override
  bool operator ==(Object other) => other is CustomResult && other.name == name && other.size == size;

  @override
  int get hashCode => name.hashCode * 31 ^ size.hashCode;
}

@bingoogolapple
Copy link
Owner Author

bingoogolapple commented Jan 9, 2019

Json 字符串和 Map、List 对象以及基本数据类型转换

  • 导入「dart:convert」
import 'dart:convert';
  • Json 字符串转换成 Map 对象
jsonDecode(Json字符串)
  • 对象转换成 Json 字符串
jsonEncode(对象)
  • 对象转成 Json 字符串并格式化
String _encode(Object object) => const JsonEncoder.withIndent('  ').convert(object);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant