Flutter使用json_serializable转模型时嵌套可选对象缺失字段报错如何解决
问题根源
你仅将User类的city属性声明为可空,不影响City类本身的解析逻辑。City类中的name是不可空String类型,当JSON的city对象缺失name字段时,json_serializable在解析City实例的阶段就会抛出类型不匹配异常,还未到给User的city属性赋值的环节,因此外层可空声明不会生效。
解决方案
方案1:为嵌套字段自定义带容错的解析逻辑(推荐)
直接在User类的city字段上通过@JsonKey注解指定自定义解析方法,捕获City解析过程中的异常,解析失败直接返回null:
@JsonSerializable() class User { int id; String name; // 新增注解,指定自定义解析方法 @JsonKey(fromJson: _nullableCityFromJson) City? city; // 其余代码不变,fromJson、toJson方法正常生成 factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); Map<String, dynamic> toJson() => _$UserToJson(this); } // 顶层的自定义解析方法,需和User类在同一个文件中 City? _nullableCityFromJson(Map<String, dynamic>? json) { if (json == null) return null; try { return City.fromJson(json); } catch (_) { // 解析失败(缺必填字段、字段类型不匹配等)直接返回null return null; } }
这种方案无需修改原有City类的定义,侵入性最低,同时能精准控制单字段的容错逻辑。
方案2:修改City类字段为可空,主动校验必填字段
如果你的业务允许City类字段可空,可以修改City定义,新增安全解析方法,校验必填字段完整才返回实例,否则返回null:
@JsonSerializable() class City { int? id; String? name; factory City.fromJson(Map<String, dynamic> json) => _$CityFromJson(json); Map<String, dynamic> toJson() => _$CityToJson(this); // 自定义安全构造方法 static City? fromJsonSafe(Map<String, dynamic>? json) { if (json == null) return null; final city = City.fromJson(json); // 校验你认为的必填字段,任意缺失就返回null if (city.id == null || city.name == null) return null; return city; } } // User类的city字段绑定该安全方法即可 @JsonKey(fromJson: City.fromJsonSafe) City? city;
内容的提问来源于stack exchange,提问作者Source30
相关产品推荐
相关产品推荐

