Flutter json_serializable解析嵌套Entity/Model报错排查
问题根因
报错来自两个核心代码错误,和@JsonConverter配置无关:
- 类型不兼容:
AddressModel与AddressEntity是完全独立的两个类,不存在继承关系。父类TestEntity中address字段的类型为List<AddressEntity>,你在子类构造中传入List<AddressModel>时,Dart静态类型检查会直接抛出类型不匹配错误。 - 序列化逻辑识别失败:你在子类中重复声明父类已有字段,
json_serializable无法正确关联父类字段与子类构造参数的映射关系,即使开启explicitToJson: true也无法自动完成嵌套对象的序列化/反序列化。
修复步骤
1. 修正AddressModel的继承关系
让AddressModel继承AddressEntity,从类型层面保证兼容,修改address_model.dart代码如下:
part 'address_model.g.dart'; @JsonSerializable() class AddressModel extends AddressEntity { const AddressModel({ required String id, required String title, }) : super( id: id, title: title, ); factory AddressModel.fromJson(Map<String, dynamic> json) => _$AddressModelFromJson(json); Map<String, dynamic> toJson() => _$AddressModelToJson(this); }
这里将构造函数改为const,和父类const构造匹配,减少不必要的实例创建开销。
2. 修正TestModel的传参逻辑
不要在子类构造中重复声明父类已存在的字段,使用Dart超类参数语法直接给父类字段传值,避免类型声明冲突,修改test_model.dart代码如下:
part 'test_model.g.dart'; @JsonSerializable(explicitToJson: true) class TestModel extends TestEntity { const TestModel({ required super.id, required List<AddressModel> super.address, }); factory TestModel.fromJson(Map<String, dynamic> json) => _$TestModelFromJson(json); @override Map<String, dynamic> toJson() => _$TestModelToJson(this); }
3. 重新生成序列化代码
执行以下命令清理旧的生成文件,重新构建序列化逻辑:
flutter pub run build_runner build --delete-conflicting-outputs
分层最佳实践
如果要严格保持Entity层的纯净(不引入任何序列化相关依赖),可以统一实现自定义JsonConverter完成Entity与Model的转换,不要在Entity文件中引入任何json_annotation相关的注解:
class NestedTypeConverter extends JsonConverter<AddressEntity, Map<String, dynamic>> { const NestedTypeConverter(); @override AddressEntity fromJson(Map<String, dynamic> json) => AddressModel.fromJson(json); @override Map<String, dynamic> toJson(AddressEntity entity) { if (entity is AddressModel) return entity.toJson(); throw UnsupportedError('Base Entity class cannot be serialized directly'); } }
在需要序列化的Model类上添加该转换器注解即可,不需要修改Entity层代码。
内容的提问来源于stack exchange,提问作者Khursheed Gaddi
相关产品推荐
相关产品推荐

