bingoogolapple / bingoogolapple.github.io

个人主页。同时也通过 Issues 记录学习笔记
http://www.bingoogolapple.cn
86 stars 22 forks source link

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

Open bingoogolapple opened 5 years ago

bingoogolapple commented 5 years ago

接入 json_serializable

dependencies:
  json_annotation: ^2.0.0

dev_dependencies:
  build_runner: ^1.1.2
  json_serializable: ^2.0.1
bingoogolapple commented 5 years ago

JsonKey 注解说明

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

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

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

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

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

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

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

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

image image image

bingoogolapple commented 5 years ago

JsonSerializable 注解说明

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

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

3、TODO

bingoogolapple commented 5 years ago

通过实现 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 commented 5 years ago

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