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. 分步请求+关联数据解析
因为两层数据是独立接口返回,不要尝试一次性解析所有数据,按照业务逻辑分两步请求:
- 先请求第一层的版本列表接口,第一层是动态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('请求版本列表失败'); } }
- 当需要加载对应版本的经文时,再从
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
相关产品推荐
相关产品推荐

