Dart:JsonSerializable与Freezed的JSON自动校验方法咨询
解决方案
1. 利用Freezed的默认值与可空类型做基础容错
如果只是想避免因字段缺失抛出_TypeError,可以给非必填字段设置默认值,或者声明为可空类型,让JsonSerializable自动填充null或默认值,而非直接报错。
示例代码:
import 'package:freezed_annotation/freezed_annotation.dart'; part 'user.freezed.dart'; part 'user.g.dart'; @freezed class User with _$User { const factory User({ // 必填字段,缺失会触发常规的参数错误(可捕获) required String id, // 给字段设置默认值,缺失时自动使用该值 @Default('Anonymous') String name, // 可空字段,缺失时自动设为null int? age, }) = _User; factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); }
这种方式属于“容错处理”,不会主动校验字段类型或存在性,但能避免无法捕获的_TypeError。
2. 在fromJson中手动添加校验逻辑
如果需要严格校验JSON结构,可以在Freezed生成的fromJson方法外层包裹自定义校验,主动检查必填字段的存在性与类型,抛出可控的异常而非_TypeError。
示例代码:
@freezed class User with _$User { const factory User({ required String id, required String name, int? age, }) = _User; factory User.fromJson(Map<String, dynamic> json) { // 校验必填字段是否存在且类型正确 if (!json.containsKey('id') || json['id'] is! String) { throw FormatException('Invalid User JSON: missing or non-string "id" field'); } if (!json.containsKey('name') || json['name'] is! String) { throw FormatException('Invalid User JSON: missing or non-string "name" field'); } return _$UserFromJson(json); } }
这种方式能精准控制校验规则,抛出的FormatException可以被正常捕获处理。
3. 替换为自带校验的序列化库
如果希望完全自动实现JSON校验,可以考虑用dart_mappable替代JsonSerializable,它与Freezed兼容,且自带完整的类型与字段存在性校验,缺失必填字段时会抛出明确的MappableException,无需手动编写校验代码。
示例代码:
import 'package:dart_mappable/dart_mappable.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'user.mapper.dart'; part 'user.freezed.dart'; @freezed @MappableClass() class User with _$User, UserMappable { const factory User({ required String id, required String name, int? age, }) = _User; static const fromJson = UserMapper.fromJson; }
当JSON缺失必填字段或类型不匹配时,会抛出包含具体错误信息的异常,便于捕获和处理。
4. 自定义代码生成扩展(进阶)
如果项目规模较大,需要批量自动生成校验逻辑,可以基于build_runner编写自定义代码生成器,在Freezed生成fromJson代码时,自动插入必填字段的校验逻辑。这种方式需要一定的代码生成知识,但能实现完全自动化的校验。
内容的提问来源于stack exchange,提问作者perojas3
相关产品推荐
相关产品推荐

