Flutter如何为嵌套JSON响应的REST API创建类?及工具疑问
Flutter处理嵌套JSON API的解决方案
关于“无需创建类用包处理JSON”的说法
这个说法部分正确。确实可以通过dart:convert的jsonDecode直接把响应转成Map<String, dynamic>,或者用dynamic类型直接通过键值对取值,不用手动写实体类。但这种方式没有类型校验,容易出现键名拼写错误,IDE也不会提供代码提示,长期维护起来成本很高。适合小型测试项目或临时场景,生产环境更推荐创建实体类来保证类型安全和代码可维护性。
为dictionaryapi.dev构建实体类的步骤
先看该API的典型响应结构(以请求单词hello为例),它是一个包含多个词条的数组,每个词条又嵌套了词义、定义等层级结构,我们从最底层的嵌套类开始构建:
1. 拆解JSON核心结构
核心层级关系:List<DictionaryEntry> → DictionaryEntry包含List<Meaning> → Meaning包含List<Definition>
2. 编写实体类
底层Definition类(对应定义内容)
class Definition { final String definition; final String? example; // 示例字段可能为空,用可空类型 Definition({ required this.definition, this.example, }); // 从Map转成实体的工厂方法 factory Definition.fromJson(Map<String, dynamic> json) { return Definition( definition: json['definition'], example: json['example'], ); } // 可选:转成Map用于序列化 Map<String, dynamic> toJson() { return { 'definition': definition, 'example': example, }; } }
中间层Meaning类(对应词性和该词性下的所有定义)
class Meaning { final String partOfSpeech; final List<Definition> definitions; Meaning({ required this.partOfSpeech, required this.definitions, }); factory Meaning.fromJson(Map<String, dynamic> json) { // 将JSON数组转成Definition对象列表 var definitionsJsonList = json['definitions'] as List; List<Definition> definitions = definitionsJsonList .map((defJson) => Definition.fromJson(defJson)) .toList(); return Meaning( partOfSpeech: json['partOfSpeech'], definitions: definitions, ); } Map<String, dynamic> toJson() { return { 'partOfSpeech': partOfSpeech, 'definitions': definitions.map((d) => d.toJson()).toList(), }; } }
顶层DictionaryEntry类(对应单个词条的完整信息)
class DictionaryEntry { final String word; final String? phonetic; // 部分单词无音标,用可空类型 final List<Meaning> meanings; DictionaryEntry({ required this.word, this.phonetic, required this.meanings, }); factory DictionaryEntry.fromJson(Map<String, dynamic> json) { // 将JSON数组转成Meaning对象列表 var meaningsJsonList = json['meanings'] as List; List<Meaning> meanings = meaningsJsonList .map((meanJson) => Meaning.fromJson(meanJson)) .toList(); return DictionaryEntry( word: json['word'], phonetic: json['phonetic'], meanings: meanings, ); } Map<String, dynamic> toJson() { return { 'word': word, 'phonetic': phonetic, 'meanings': meanings.map((m) => m.toJson()).toList(), }; } }
3. 用实体类解析API响应
结合http包发起请求并解析:
import 'dart:convert'; import 'package:http/http.dart' as http; Future<List<DictionaryEntry>> fetchWordDefinition(String word) async { final response = await http.get( Uri.parse('https://api.dictionaryapi.dev/api/v2/entries/en/$word'), ); if (response.statusCode == 200) { List<dynamic> jsonList = jsonDecode(response.body); return jsonList .map((entryJson) => DictionaryEntry.fromJson(entryJson)) .toList(); } else { throw Exception('Failed to load word definition'); } }
4. 可选:用代码生成工具简化开发
如果不想手动编写fromJson和toJson,可以用json_serializable包自动生成序列化代码:
- 在
pubspec.yaml添加依赖:json_annotation、json_serializable、build_runner - 在类上添加
@JsonSerializable()注解 - 运行命令
flutter pub run build_runner build自动生成转换代码
内容的提问来源于stack exchange,提问作者DktPhl2018
相关产品推荐
相关产品推荐

