Flutter Dart中用json_serializable解析类型不统一的JSON
解决json_serializable解析混合类型字段的问题
问题分析
第三方API返回的retro字段类型不统一:大部分是布尔值(true/false),但存在空字符串("")的情况,直接用as bool强制转换会抛出类型转换异常。
解决方案
方法一:自定义字段转换函数(推荐)
利用json_serializable的@JsonKey注解,为retro字段指定自定义转换逻辑,兼容布尔值和空字符串类型。
修改后的实体类代码:
import 'package:json_annotation/json_annotation.dart'; @JsonSerializable() class UserItem { int id; String email; String gender; @JsonKey(name: 'ip_address') String ipAddress; String name; // 为retro字段指定自定义转换函数 @JsonKey(fromJson: _retroFromJson) bool retro; UserItem(this.id, this.email, this.gender, this.ipAddress, this.name, this.retro); factory UserItem.fromJson(Map<String, dynamic> json) => _$UserItemFromJson(json); Map<String, dynamic> toJson() => _$UserItemToJson(this); // 自定义转换函数:处理布尔值、空字符串,默认返回false static bool _retroFromJson(dynamic value) { if (value is bool) { return value; } else if (value is String) { // 空字符串视为false,可根据业务需求调整 return value.isNotEmpty ? bool.tryParse(value) ?? false : false; } // 其他未知类型默认返回false return false; } } // 以下部分可通过build_runner自动生成,无需手动修改 UserItem _$UserItemFromJson(Map<String, dynamic> json) => UserItem( json['id'] as int, json['email'] as String, json['gender'] as String, json['ip_address'] as String, json['name'] as String, UserItem._retroFromJson(json['retro']), ); Map<String, dynamic> _$UserItemToJson(UserItem instance) => <String, dynamic>{ 'id': instance.id, 'email': instance.email, 'gender': instance.gender, 'ip_address': instance.ipAddress, 'name': instance.name, 'retro': instance.retro, };
方法二:手动修改生成的解析函数
如果不想添加自定义转换函数,也可以直接修改_$UserItemFromJson中retro字段的解析逻辑,对类型进行判断:
UserItem _$UserItemFromJson(Map<String, dynamic> json) => UserItem( json['id'] as int, json['email'] as String, json['gender'] as String, json['ip_address'] as String, json['name'] as String, // 增加类型判断,兼容布尔值和空字符串 json['retro'] is bool ? json['retro'] as bool : (json['retro'] as String).isEmpty ? false : bool.tryParse(json['retro']) ?? false, );
注意:这种方法的缺点是,每次通过
build_runner重新生成代码时,修改的内容会被覆盖,需要重新调整。
验证效果
修改后重新运行flutter pub run build_runner build生成代码,即可正常解析包含空字符串retro字段的JSON数据,不会再抛出类型转换异常。
内容的提问来源于stack exchange,提问作者Sandeep Kumar
相关产品推荐
相关产品推荐

