Flutter开发之JSON序列化

一、背景

目前手上开发的项目,出于便于维护的角度考虑,选择了可以跨端的Flutter进行开发。
作为一个Android开发er,使用dart这种语言进行开发还是多少有些不习惯。大家都知道,Java中对JSON进行序列化的库有很多,比如Gson,FastJson,都可以快速将JSON字符串转成对象——然而在flutter中却没有这么简单。
这些库的原理运用到了反射机制,而反射机制在flutter中是被禁用的。(虽然dart语言有反射机制)

  • flutter支持了很久的Tree-shaking可以通过工具将用不到的代码从发布版本中去掉,该方式可以显著优化App的体积。由于反射会默认让代码进行隐式使用,工具不能知道哪一部分在运动时不会被用到,所以冗余代码很难被清除,如果使用反射,App的体积难以优化。
  • dartson在运行时使用到了反射,因此在flutter中不能兼容。

这里记录一下flutter在使用时对JSON进行序列化的方法

二、JSON序列化方法

flutter中有两种常用的策略:

  1. 手动序列化
  2. 代码生成
    如果对象字段不多,手动序列化也可,要是字段比较多,推荐用代码生成(非要头铁手撸代码,也行8)。

三、手动序列化JSON

模型类User.dart

class User {
  final String name;
  final String email;

  User(this.name, this.email);

  User.fromJson(Map json)
      : name = json['name'],
        email = json['email'];

  Map toJson() => {
        'name': name,
        'email': email,
      };
}

获取User实例:

Map userMap = jsonDecode(jsonString);
var user = User.fromJson(userMap);

将User实例转为JSON:

String json = jsonEncode(user);

PS: User.fromJson() 和 User.toJson() 方法最好进行单元测试验证。

四、使用json_serializable序列化JSON

除了json_serializable之外, built_Value也可以进行JSON序列化,且提供了更高层次的方法,让定义为不可变的类也能够被序列化为JSON。

1.设置json_serializable

在项目中配置json_serializable需要一个常规依赖,以及两个 dev 依赖。(dev 依赖 是不包括在App源代码中的依赖——即会被用在开发环境中)
pubspec.yaml文件:

dependencies:
     # Your other regular dependencies here
     json_annotation: 
dev_dependencies:
     # Your other dev_dependencies here
     build_runner: 
     json_serializable: 

2. 创建模型类

- 基础实体类

在实体类User.dart上加注解@JsonSerializable(),

import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
@JsonSerializable()
class User {
    User(this.name, this.email);
    String name;
    String email;
    factory User.fromJson(Map json) => _$UserFromJson(json);
    Map toJson() => _$UserToJson(this);
}

如果需要,可以自定义命名策略,如:

@JsonKey(name: 'registration_date_millis')
final int registrationDateMillis;

@JsonKey 声明方法包括:

  const JsonKey({
   this.defaultValue,
   this.disallowNullValue,
   this.fromJson,//自定义该字段fromJson的方法
   this.ignore,//使用json_serializable生成时忽略该字段
   this.includeIfNull,
   this.name,//自定义命名策略
   this.nullable,
   this.required,//要求如果JSON中不存在该字段,则会抛出异常
   this.toJson,//自定义该字段toJson的方法
   this.unknownEnumValue,
 });

- 运行代码生成工具

在项目根目录运行如下代码
一次性代码生成:

flutter pub run build_runner build

持续代码生成:

flutter pub run build_runner watch

该方法会监听项目中的文件变化,自动构建文件。

- 为嵌套类生成代码

在实体类的注解中加入explicitToJson:true参数:

@JsonSerializable(explicitToJson: true)
class User{
    User(this.name,this.address);
	String name;
	Address address;
	factory User.fromJson(Map json) => _$UserFromJson(json);
    Map toJson() => _$UserToJson(this);
}

你可能感兴趣的:(flutter)