Flutter Dart解析JSON时忽略可空引用类的必填字段
解决Dart json_serializable中可空嵌套类强制加载的问题
我定义了Delivery类,其中引用了ShippingDoc、VhcApplication等可空嵌套类(因为不确定这些类何时会有有效值)。但发现即使把这些嵌套类声明为可空,json_serializable仍会尝试加载它们的所有字段——哪怕对应的JSON字段是null或不存在,这不符合预期。比如当前VhcApplication对应的JSON值为空,但框架仍会触发它的字段加载逻辑,导致问题。
相关代码
import 'package:json_annotation/json_annotation.dart'; part 'delivery.g.dart'; enum DeliveryStatus { @JsonValue(0)ToBeConfirmed, @JsonValue(1)Ongoing, @JsonValue(2)Received, @JsonValue(3)Cancelled, } @JsonSerializable(explicitToJson: true) class Delivery{ Delivery({ this.id, this.shippingDoc, this.shippingDocId, this.vhc, this.vhcId, this.aic, this.aicId, required this.status, required this.receivedOnDatetime, this.receivedBy, required this.receivedById, this.remarks, this.isConfirmed, this.isCancelled, this.confirmedOnDatetime, this.cancelledOnDatetime, }); @JsonKey(name: 'id') String? id = ""; @JsonKey(name: 'shipping_doc') ShippingDoc? shippingDoc; @JsonKey(name: 'shipping_doc_id') String? shippingDocId = ""; @JsonKey(name: 'vhc') VhcApplication? vhc; @JsonKey(name: 'vhc_id') String? vhcId = ""; @JsonKey(name: 'aic') VhcApplication? aic; @JsonKey(name: 'aic_id') String? aicId = ""; @JsonKey(name: 'status') DeliveryStatus status = DeliveryStatus.ToBeConfirmed; @JsonKey(name: 'received_on_datetime') String receivedOnDatetime = ''; @JsonKey(name: 'received_by') User? receivedBy; @JsonKey(name: 'received_by_id') String receivedById = ""; @JsonKey(name: 'remarks') String? remarks = ""; @JsonKey(name: 'is_confirmed') bool? isConfirmed = false; @JsonKey(name: 'is_cancelled') bool? isCancelled = false; @JsonKey(name: 'confirmed_on_datetime') String? confirmedOnDatetime = ""; @JsonKey(name: 'cancelled_on_datetime') String? cancelledOnDatetime = ""; factory Delivery.fromJson(Map<String, dynamic> json) => _$DeliveryFromJson(json); Map<String, dynamic> toJson() => _$DeliveryToJson(this); }
解决方法
1. 给可空嵌套类字段添加includeIfNull: false
在@JsonKey注解中加入includeIfNull: false,这样当字段值为null时,序列化和反序列化过程都会跳过该字段,不会触发嵌套类的加载逻辑。修改后的字段示例:
@JsonKey(name: 'vhc', includeIfNull: false) VhcApplication? vhc; @JsonKey(name: 'aic', includeIfNull: false) VhcApplication? aic; @JsonKey(name: 'received_by', includeIfNull: false) User? receivedBy;
2. 确保嵌套类的fromJson支持空值
检查VhcApplication、ShippingDoc等嵌套类的fromJson实现,确保它们能正确处理null输入。比如:
factory VhcApplication.fromJson(Map<String, dynamic>? json) { if (json == null || json.isEmpty) return null; // 正常解析逻辑 }
3. 按需关闭explicitToJson
如果你的业务场景不需要把嵌套类序列化为完整JSON对象,仅需保留ID字段,可以去掉@JsonSerializable中的explicitToJson: true。这样框架不会递归处理嵌套类,仅处理基本数据类型字段。
原理说明
json_serializable默认会处理所有声明的字段,即使是可空类型——因为explicitToJson: true会触发递归的序列化/反序列化流程。includeIfNull: false的作用是告诉框架:当字段为null时,不要对其进行任何处理,从而避免不必要的嵌套类加载操作。
内容的提问来源于stack exchange,提问作者rminaj
相关产品推荐
相关产品推荐

