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

Flutter如何处理含关联JSON链接的REST API嵌套数据解析

Flutter 处理关联嵌套JSON数据的实现方案

你遇到的是典型的跨接口关联JSON数据处理场景,按照以下步骤实现即可:

1. 先定义对应的数据模型

根据两层JSON的结构,分别定义三个Dart类:

  • 第一层的翻译版本信息类Edition
  • 第二层的单条经文类Verse
  • 第二层的经文集合返回类QuranResponse

示例代码如下:

// 翻译版本模型
class Edition {
  final String name;
  final String author;
  final String language;
  final String direction;
  final String source;
  final String comments;
  final String link;
  final String linkmin;

  Edition({required this.name, required this.author, required this.language, required this.direction, required this.source, required this.comments, required this.link, required this.linkmin});

  // JSON转实体方法
  factory Edition.fromJson(Map<String, dynamic> json) {
    return Edition(
      name: json['name'],
      author: json['author'],
      language: json['language'],
      direction: json['direction'],
      source: json['source'],
      comments: json['comments'],
      link: json['link'],
      linkmin: json['linkmin'],
    );
  }
}

// 单条经文模型
class Verse {
  final int chapter;
  final int verse;
  final String text;

  Verse({required this.chapter, required this.verse, required this.text});

  factory Verse.fromJson(Map<String, dynamic> json) {
    return Verse(
      chapter: json['chapter'],
      verse: json['verse'],
      text: json['text'],
    );
  }
}

// 经文集合返回模型
class QuranResponse {
  final List<Verse> quran;

  QuranResponse({required this.quran});

  factory QuranResponse.fromJson(Map<String, dynamic> json) {
    var verseList = json['quran'] as List;
    List<Verse> verses = verseList.map((i) => Verse.fromJson(i)).toList();
    return QuranResponse(quran: verses);
  }
}

如果不想手写序列化逻辑,可以用官方的json_serializable包自动生成解析代码,减少手写错误。

2. 分步请求+关联数据解析

因为两层数据是独立接口返回,不要尝试一次性解析所有数据,按照业务逻辑分两步请求:

  1. 先请求第一层的版本列表接口,第一层是动态Key的Map结构,解析时直接转换为Map<String, Edition>即可,示例:
import 'package:http/http.dart' as http;
import 'dart:convert';

Future<Map<String, Edition>> fetchEditionList() async {
  final response = await http.get(Uri.parse('你的第一层API地址'));
  if (response.statusCode == 200) {
    Map<String, dynamic> jsonMap = json.decode(response.body);
    Map<String, Edition> editionMap = {};
    jsonMap.forEach((key, value) {
      editionMap[key] = Edition.fromJson(value);
    });
    return editionMap;
  } else {
    throw Exception('请求版本列表失败');
  }
}
  1. 当需要加载对应版本的经文时,再从Edition实例中取出link字段发起第二次请求,解析成QuranResponse即可:
Future<QuranResponse> fetchQuranByEdition(Edition edition) async {
  final response = await http.get(Uri.parse(edition.link));
  if (response.statusCode == 200) {
    return QuranResponse.fromJson(json.decode(response.body));
  } else {
    throw Exception('请求经文内容失败');
  }
}

3. 可选优化方案

  • 按需加载:不要一次性请求所有版本的经文,用户选中对应版本后再发起对应经文请求,避免占用过多带宽和内存
  • 本地缓存:将已经请求过的经文数据存储到本地数据库,下次启动无需重复请求
  • 章节拆分加载:如果经文内容过大,也可以按照章节拆分请求,避免一次性加载大量内容导致UI卡顿

相关参考

Flutter官方文档的JSON处理、网络请求模块已经覆盖了这类场景的处理教程,直接按照官方标准流程实现即可,无需额外找第三方教程。


内容的提问来源于stack exchange,提问作者Mohammed Bekele

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 02:06:03