如何为嵌套 JSON 中存在 JSON 列表的嵌套 JSON 创建模型?

Posted

技术标签:

【中文标题】如何为嵌套 JSON 中存在 JSON 列表的嵌套 JSON 创建模型?【英文标题】:How to Create Model for Nested JSON where There is a List of JSON Inside Nested JSON? 【发布时间】:2022-01-16 19:23:24 【问题描述】:

我有一个 JSON 响应的结构,如下面的代码(示例):


  "data": 
    "items": [
      
        "id": 1,
        "name": "Baburiki",
        "jutsu_variant": [
          
            "jutsu_name": "wind release",
            "damage": 1200,
          ,
        ], 
      ,
      
        "id": 2,
        "name": "Zee",
        "jutsu_variant": [
          
            "jutsu_name": "wind release",
            "damage": 1200,
          ,
          
            "jutsu_name": "kage bunshin",
            "damage": 2000,
          ,
        ], 
      ,
    ],
  ,

items 键上有一个 JSON 列表,在该键中,jutsu_variant 键上有另一个 JSON 列表。

我已经创建了一个类模型来存储 JSON 响应,如下面的代码

class ShinobiData 
  int? id;
  String? shinobiName;
  JutsuVariant? jutsuVariant;

  ShinobiData(
    this.id,
    this.shinobiName,
    this.jutsuVariant,
  );

  factory ShinobiData.fromJson(Map<String, dynamic> json) 
    return ShinobiData(
      id: json['id'],
      shinobiName: json['name'],
      jutsuVariant: json['jutsu_variant'],
    );
  


class JutsuVariant 
  String? jutsuName;
  int? jutsuDamage;

  JutsuVariant(this.jutsuName, this.jutsuDamage);

  factory JutsuVariant.fromJson(Map<String, dynamic> json) 
    return JutsuVariant(
      jutsuName: json['jutsu_name'],
      jutsuDamage: json['damage'],
    );
  

如果jutsu_variant 键上没有list,则模型工作正常。

这是我获取 POST 请求的 API 响应的类。 (使用提供者状态管理创建)

import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:learning_api/model/shinobi_model.dart';

class CatalogResponse with ChangeNotifier 
  Map<String, dynamic> _map = ;
  bool _error = false;
  String _errorMessage = '';
  List<ShinobiData> _shinobis = [];

  Map<String, dynamic> get map => _map;

  List<ShinobiData> get shinobis => _shinobis;

  bool get error => _error;

  String get errorMessage => _errorMessage;

  Future<void> get fetchData async 
    var _finalBody = 
      'page': 1,
      'items_per_page': 5,
    ;

    String _body = const JsonEncoder().convert(_finalBody);

    final response = await http.post(
      Uri.parse('https://***/url'),
      body: _body,
      headers: <String, String>
        'Content-Type': 'application/json; charset=UTF-8',
      ,
    );

    if (response.statusCode == 200) 
      try 
        _map = (jsonDecode(response.body))['data'];
        List<dynamic> _listShinobi = (_map)['items'];

        // this loop will add each item in the items key 
        for (int i = 0; i < _listShinobi.length; i++)
          _shinobis.add(CatalogData.fromJson(_listItem[i]));

        _error = false;
       catch (e) 
        _error = true;
        _errorMessage = e.toString();
        _map = ;
        _catalogs = [];
      
     else 
      _error = true;
      _errorMessage = "Error: It would be your internet connection";
      _map = ;
      _catalogs = [];
    
    notifyListeners();
  

  void initialValues() 
    _map = ;
    _catalogs = [];
    _error = false;
    _errorMessage = "";
    notifyListeners();
  

上面的代码非常适合nameid 键调用。但是在调用jutsu_variant 键时会出现问题。我应该怎么做才能调用jutsu_namejutsu_variant 键中的damage 键的值?

这样的案例在任何教程资源中都不存在。也许你的答案在未来会很有价值。提前谢谢你

【问题讨论】:

【参考方案1】:

在您的 ShinobiData 班级中 你应该使用List&lt;JutsuVariant&gt; 而不是 JutsuVariant

您可以使用json_serializable 甚至freezed 为您自动生成这些文件

【讨论】:

【参考方案2】:

这个IDE插件JosnToDart对我来说非常方便。它可以生成响应模型,只需将 json 粘贴到此。更多我们可以在生成时选择可空或不可空选项。

【讨论】:

以上是关于如何为嵌套 JSON 中存在 JSON 列表的嵌套 JSON 创建模型?的主要内容,如果未能解决你的问题,请参考以下文章

如何为来自 SpringBoot 后端代码的嵌套 JSON 响应在 angular8(TypeScript) 或更高版本中定义模型类

如何为 Hive 创建架构以使用 SerDe 解析深度嵌套的 json(Azure Application Insights 输出)?

如何为红移光谱中的嵌套 Parquet 类型创建外部表

如何处理 JSON 中常见的嵌套数据?哪种结构最好?

如何为嵌套对象或同一父对象中的对象列表定义 GraphQLObjectType

python读取json格式文件大量数据,以及python字典和列表嵌套用法详解