Dart使用json_serializable嵌套对象反序列化类型转换报错
问题根因
报错核心是json_serializable默认配置下,不会自动递归调用嵌套自定义类型的toJson方法。你当前生成的_$OfficesListToJson方法直接将List<Office>类型的offices字段塞入返回结果,导致list1.toJson()输出的结构中,offices字段存储的是Office实例列表,而非序列化后的Map<String, dynamic>列表,反序列化执行e as Map<String, dynamic>强转时就会抛出类型不匹配异常。
修复方案
两种方案选其一即可,修复后重新执行代码生成命令dart run build_runner build --delete-conflicting-outputs(Flutter项目替换为flutter pub run build_runner build --delete-conflicting-outputs)即可正常运行。
- 全局配置(推荐,一劳永逸):在项目根目录新建/修改
build.yaml文件,添加如下配置,全局开启嵌套对象自动序列化:
targets: $default: builders: json_serializable: options: explicit_to_json: true
- 单类配置:如果不需要全局生效,直接在需要嵌套序列化的类上的
@JsonSerializable注解中开启参数即可:
@JsonSerializable(explicitToJson: true) class OfficesList { List<Office> offices; OfficesList({required this.offices}); factory OfficesList.fromJson(Map<String, dynamic> json) => _$OfficesListFromJson(json); Map<String, dynamic> toJson() => _$OfficesListToJson(this); }
配置生效后重新生成的toJson方法会自动补全嵌套对象的序列化逻辑,生成代码如下:
Map<String, dynamic> _$OfficesListToJson(OfficesList instance) => <String, dynamic>{ 'offices': instance.offices.map((e) => e.toJson()).toList(), };
json_serializable 自动生成代码适配规则
- 默认行为:
explicitToJson默认值为false,生成toJson时不会递归处理嵌套的自定义类型,直接返回原对象实例,该设计是为了避免无意义的深层序列化带来的性能损耗。 - 嵌套序列化触发条件:只要给类设置
explicitToJson: true,生成代码时就会递归扫描所有字段,对拥有toJson方法的自定义类型自动调用对应序列化逻辑,支持任意层级的对象嵌套。 - 反序列化逻辑默认支持嵌套:你当前生成的
fromJson方法已经正确实现了嵌套类型的转换逻辑,只要toJson输出的结构符合Map嵌套的标准JSON结构,反序列化就不会抛出类型错误。 - 你的测试代码逻辑本身没有问题,修复配置重新生成代码后即可正常运行,输出正确的序列化结果。
内容的提问来源于stack exchange,提问作者Dmitrii Domrachev
相关产品推荐
相关产品推荐

