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

如何在Freezed中通过一个字段获取两个不同的JSON值?

在Freezed中处理多JSON字段映射到同一模型属性的问题

问题背景

现有基于Freezed的Dto模型类:

@freezed
abstract class Dto implements _$Dto {
  const factory Dto({
    String? name,
    String? url,
  }) = _Dto;

  factory Dto.fromJson(Map<String, dynamic> json) =>
      _$DtoFromJson(json);
}

需要兼容两种JSON响应格式:

  1. 包含display_picture_url字段的JSON:
{
  "name": "superuser root",
  "display_picture_url": "/media_server/user.jpg"
}
  1. 包含picture_url字段的JSON:
{
  "name": "superuser root",
  "picture_url": "/media_server/user.jpg"
}

非Freezed环境下可以直接在fromJson中判断字段存在性来赋值,但Freezed生成的序列化逻辑需要特殊处理。

解决方案

方法一:自定义fromJson预处理JSON

直接在自定义的fromJson方法中预处理原始JSON,将两个可能的字段统一映射为模型中的url字段,再交给Freezed生成的解析方法处理:

@freezed
abstract class Dto implements _$Dto {
  const factory Dto({
    String? name,
    String? url,
  }) = _Dto;

  factory Dto.fromJson(Map<String, dynamic> json) {
    // 复制原始JSON避免修改原对象
    final processedJson = Map<String, dynamic>.from(json);
    
    // 优先取display_picture_url,不存在则取picture_url
    if (processedJson.containsKey('display_picture_url')) {
      processedJson['url'] = processedJson.remove('display_picture_url');
    } else if (processedJson.containsKey('picture_url')) {
      processedJson['url'] = processedJson.remove('picture_url');
    }
    
    // 调用Freezed生成的解析方法
    return _$DtoFromJson(processedJson);
  }
}

这种方法逻辑直观,和非Freezed环境下的写法思路一致,适合处理多字段映射的场景。

方法二:使用@JsonKey自定义字段解析逻辑

通过@JsonKey的fromJson参数,为url字段指定自定义解析函数,从整个JSON对象中匹配目标字段:

// 自定义解析函数
String? _resolveUrl(Map<String, dynamic> json) {
  if (json.containsKey('display_picture_url')) {
    return json['display_picture_url'] as String?;
  } else if (json.containsKey('picture_url')) {
    return json['picture_url'] as String?;
  }
  return null;
}

@freezed
abstract class Dto implements _$Dto {
  const factory Dto({
    String? name,
    // 为url字段指定自定义解析逻辑
    @JsonKey(fromJson: _resolveUrl) String? url,
  }) = _Dto;

  factory Dto.fromJson(Map<String, dynamic> json) => _$DtoFromJson(json);
}

这种方法更贴合注解式序列化的风格,适合单一字段的多来源解析场景。

内容的提问来源于stack exchange,提问作者Meshkat Shadik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 06:52:32