基于Freezed与json_serializable的复杂对象解析错误通用处理方案问询
基于Freezed + json_serializable的字段解析错误通用处理方案
针对后端返回字段类型不匹配、嵌套对象解析失败导致整个模型崩溃的问题,核心解决方案是通过自定义JsonConverter捕获解析异常,让单个字段解析失败时返回默认值,不影响整个对象的解析。
一、单一类型字段的容错处理(以示例中id字段为例)
后端返回的id可能是String或int,默认解析会抛出类型转换异常,我们可以写一个专用转换器处理这种场景:
1. 编写类型安全转换器
import 'package:json_annotation/json_annotation.dart'; // 处理String类型的容错转换:支持int转String,解析失败返回空字符串 class SafeStringConverter implements JsonConverter<String, dynamic> { const SafeStringConverter(); @override String fromJson(dynamic json) { if (json is String) return json; if (json is int) return json.toString(); // 其他类型(如null、bool等)直接返回默认值 return ''; } @override dynamic toJson(String object) => object; }
2. 在模型字段上应用转换器
修改Interest类,给id字段添加转换器注解:
@freezed class Interest with _$Interest { const factory Interest({ @Default('') @SafeStringConverter() String id, required String slug, required String name, required String image, required bool isPublic, }) = _Interest; factory Interest.fromJson(Map<String, dynamic> json) => _$InterestFromJson(json); }
此时即使id是int类型,也会自动转为String;解析失败时直接使用@Default指定的空字符串。
二、通用类型的容错转换器(支持任意类型)
如果需要处理多种类型的字段(如int、bool、嵌套对象),可以编写通用转换器,支持自定义解析逻辑和默认值:
1. 通用转换器实现
class SafeTypeConverter<T> implements JsonConverter<T, dynamic> { final T defaultValue; final T Function(dynamic) parser; const SafeTypeConverter({required this.defaultValue, required this.parser}); @override T fromJson(dynamic json) { try { return parser(json); } catch (_) { // 捕获所有解析异常(类型转换、格式错误等),返回默认值 return defaultValue; } } @override dynamic toJson(T object) => object; }
2. 多场景应用示例
- 处理required字符串字段:确保解析失败时返回有效值,满足required约束
@SafeTypeConverter( defaultValue: '', parser: (json) => json as String, ) required String slug, - 处理嵌套对象:如果嵌套对象解析失败,返回默认构造的空对象
// 假设存在User模型,需先定义User.fromJson @Default(User()) @SafeTypeConverter( defaultValue: User(), parser: (json) => User.fromJson(json as Map<String, dynamic>), ) User owner, - 处理布尔类型:支持数字转bool(如1→true,0→false),失败返回false
@Default(false) @SafeTypeConverter( defaultValue: false, parser: (json) { if (json is bool) return json; if (json is int) return json == 1; throw FormatException(); }, ) bool isPublic,
三、关键注意事项
- 所有
required字段必须确保转换器返回非null值,或配合@Default提供默认值,避免Dart编译时错误 - 转换器的
parser逻辑需覆盖后端可能返回的所有类型(如int转String、数字转bool) - 嵌套对象的容错处理需依赖其自身的
fromJson方法,同时在转换器中指定默认的空对象作为fallback
内容的提问来源于stack exchange,提问作者deniskrr
相关产品推荐
相关产品推荐

