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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 00:26:12