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

同一接口返回不同JSON,如何转换为Dart模型?

解决同一API返回不同JSON结构的Dart模型转换问题

针对同一接口返回不同JSON结构的情况,给你几个实用的处理方案:

方案1:定义统一模型,通过字段映射兼容不同结构

创建一个包含所有可能字段的模型类,利用json_serializable的@JsonKey注解,把不同JSON里的同义字段映射到模型的同一个属性上。这样不管返回哪种结构,都能统一解析成同一个模型对象。

示例代码:

import 'package:json_annotation/json_annotation.dart';

part 'unified_model.g.dart';

@JsonSerializable()
class UnifiedContent {
  final String title;

  // 同时兼容"thumbnail"和"thumb"字段
  @JsonKey(name: 'thumbnail', defaultValue: '')
  final String thumbnail;
  @JsonKey(name: 'thumb', defaultValue: '')
  String get thumb => thumbnail.isNotEmpty ? thumbnail : '';

  // 同时兼容"url"和"video_url"字段
  @JsonKey(name: 'url', defaultValue: '')
  final String url;
  @JsonKey(name: 'video_url', defaultValue: '')
  String get videoUrl => url.isNotEmpty ? url : '';

  // 同时兼容"urlList"和"videoUrlList"字段
  @JsonKey(name: 'urlList', defaultValue: [])
  final List<String> urlList;
  @JsonKey(name: 'videoUrlList', defaultValue: [])
  List<String> get videoUrlList => urlList.isNotEmpty ? urlList : [];

  UnifiedContent({
    required this.title,
    required this.thumbnail,
    required this.url,
    required this.urlList,
  });

  factory UnifiedContent.fromJson(Map<String, dynamic> json) =>
      _$UnifiedContentFromJson(json);

  Map<String, dynamic> toJson() => _$UnifiedContentToJson(this);
}

这种方式的好处是上层代码不用区分响应类型,直接使用统一模型的getter获取对应数据即可。

方案2:先判断响应类型,再分别解析成对应模型

如果两种结构差异很大,没必要强行统一,可以先把响应转成Map<String, dynamic>,通过判断特定字段的存在来区分类型,再分别实例化不同的模型类。

首先定义两个模型类:

// 对应JSON响应1的模型
class ContentType1 {
  final String title;
  final String thumbnail;
  final String url;
  final List<String> urlList;

  ContentType1({
    required this.title,
    required this.thumbnail,
    required this.url,
    required this.urlList,
  });

  factory ContentType1.fromJson(Map<String, dynamic> json) {
    return ContentType1(
      title: json['title'],
      thumbnail: json['thumbnail'],
      url: json['url'],
      urlList: List<String>.from(json['urlList']),
    );
  }
}

// 对应JSON响应2的模型
class ContentType2 {
  final String title;
  final String thumb;
  final String videoUrl;
  final List<String> videoUrlList;

  ContentType2({
    required this.title,
    required this.thumb,
    required this.videoUrl,
    required this.videoUrlList,
  });

  factory ContentType2.fromJson(Map<String, dynamic> json) {
    return ContentType2(
      title: json['title'],
      thumb: json['thumb'],
      videoUrl: json['video_url'],
      videoUrlList: List<String>.from(json['videoUrlList']),
    );
  }
}

然后在解析的时候做判断:

dynamic parseResponse(Map<String, dynamic> json) {
  if (json.containsKey('thumbnail')) {
    return ContentType1.fromJson(json);
  } else if (json.containsKey('thumb')) {
    return ContentType2.fromJson(json);
  }
  throw Exception('未知的响应类型');
}

上层代码拿到解析结果后,可以通过is关键字判断类型,再做对应处理:

var responseData = parseResponse(jsonMap);
if (responseData is ContentType1) {
  // 处理类型1的数据
} else if (responseData is ContentType2) {
  // 处理类型2的数据
}

方案3:使用动态类型(不推荐)

如果只是临时快速处理,可以直接用Map<String, dynamic>或者dynamic类型来存取数据,但这种方式会丢失类型检查,代码可读性和可维护性差,不建议在正式项目中使用。

内容的提问来源于stack exchange,提问作者shakti goyal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 16:05:26