自定义JsonConverter编译后对fromJson无效问题排查
问题:自定义JsonConverter未生效,反序列化空数组meta字段报错
我尝试为类中的特定字段创建自定义JsonConverter,原因是调用的API返回的meta字段可能是字典或空数组,但需要始终保存为Map<String, dynamic>。但执行flutter pub run build_runner build后,生成的代码未使用自定义转换器,反序列化meta为空数组的JSON时触发错误。
原代码
Tag类及自定义Converter
import 'package:json_annotation/json_annotation.dart'; part 'tag.g.dart'; @JsonSerializable() class Tag { int? id; int? count; String? description; Uri? link; String? name; String? slug; String? taxonomy; @EmptyMetaToMapConverter() Map<String, dynamic>? meta; Tag(); factory Tag.fromJson(Map<String, dynamic> json) => _$TagFromJson(json); Map<String, dynamic> toJson() => _$TagToJson(this); } class EmptyMetaToMapConverter extends JsonConverter<Map, Object?> { const EmptyMetaToMapConverter(); @override Map<String, dynamic> fromJson(Object? json) { if (json is List) return {}; if (json is Map<String, dynamic>) return json; throw Exception(); } @override Map toJson(Map object) => object; }
生成的tag.g.dart关键部分
// ... Tag _$TagFromJson(Map<String, dynamic> json) => Tag() // ...其他字段解析 ..meta = json['meta'] as Map<String, dynamic>?; // 自定义Converter未生效 // ...
环境信息
- Flutter版本:3.16.8
- 依赖版本:
json_serializable: ^6.7.1 build_runner: ^2.4.8 json_annotation: ^4.8.1
问题原因
自定义Converter的泛型参数与字段类型不匹配:
- 字段
meta的类型是Map<String, dynamic>?(可空),但Converter定义为JsonConverter<Map, Object?>,泛型中的Map是非空类型,导致json_serializable无法识别该转换器适用于这个可空字段。 - 另外
fromJson返回的Map<String, dynamic>与Converter泛型的Map也存在精度不匹配问题。
修正方案
调整自定义Converter的泛型参数,使其与字段类型完全匹配,同时完善空值处理:
修正后的Converter和Tag类
import 'package:json_annotation/json_annotation.dart'; part 'tag.g.dart'; @JsonSerializable() class Tag { int? id; int? count; String? description; Uri? link; String? name; String? slug; String? taxonomy; @EmptyMetaToMapConverter() Map<String, dynamic>? meta; Tag(); factory Tag.fromJson(Map<String, dynamic> json) => _$TagFromJson(json); Map<String, dynamic> toJson() => _$TagToJson(this); } // 泛型改为与字段匹配的Map<String, dynamic>? 和 Object? class EmptyMetaToMapConverter extends JsonConverter<Map<String, dynamic>?, Object?> { const EmptyMetaToMapConverter(); @override Map<String, dynamic>? fromJson(Object? json) { if (json == null) return null; // 处理null情况 if (json is List) return {}; // 空数组转为空Map if (json is Map<String, dynamic>) return json; // 直接返回字典 throw Exception('Unsupported type for meta field: ${json.runtimeType}'); } @override Map<String, dynamic>? toJson(Map<String, dynamic>? object) => object; // 适配可空类型 }
重新生成代码
执行以下命令重新生成序列化代码:
flutter pub run build_runner build --delete-conflicting-outputs
生成后的tag.g.dart中,meta字段会正确调用转换器:
// ... Tag _$TagFromJson(Map<String, dynamic> json) => Tag() // ...其他字段解析 ..meta = const EmptyMetaToMapConverter().fromJson(json['meta']); // ...
这样就能正确处理meta字段为字典、空数组或null的情况,避免反序列化报错。
内容的提问来源于stack exchange,提问作者paulchoix
相关产品推荐
相关产品推荐

