You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 02:33:22