Flutter JSON 解码

Posted

技术标签:

【中文标题】Flutter JSON 解码【英文标题】:Flutter JSON decoding 【发布时间】:2022-01-18 01:45:48 【问题描述】:

我有一个网站,其中包含 Flutter 读取的生成 JSON。 JSON 包含一个名称列表,我希望将其显示为列中的列表。 启动应用程序时,它显示在中心:

FormatException: SyntaxError: Unexpected token < in JSON at position 0

我已经确保检查 JSON 是否无效,但没有问题。

    
    "data": [
        
            "Name": "PlayerOne",
            "Data": "\"isOnline\":false"
        ,
        
            "Name": "PlayerTwo",
            "Data": "\"isOnline\":false"
        
    ]

如果 isOnline 设置为 true,则应该是所有名称。 这是解码 JSON 的工厂函数:

    factory PlayersOnline.fromJson(Map<String, dynamic> json) 
    return PlayersOnline(
        Name: json["data.Name"],
        isOnline: json["data.Data"]
    );

以及来自 build 的未来建设者:

    @override
  Widget build(BuildContext context) 

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text("Test"),
        ),
        body: FutureBuilder(
          future: fetchOnline(),
          builder: (BuildContext context, AsyncSnapshot snapshot) 
            if (snapshot.hasData) 
              return Text(snapshot.data!);
             else if (snapshot.hasError) 
              return Text("$snapshot.error");
            

            return const CircularProgressIndicator();
          ,
        )
      ),
    );


  

申请方法:

Future<PlayersOnline> fetchOnline() async 

  final response = await http.get(Uri.parse("serwer.fabrykacraft.pl"));

  if (response.statusCode == 200) 


    return PlayersOnline.fromJson(json.decode(response.body));
   else 
    throw Exception("Can't fetch data");

  


虽然 JSON 是通过 phpmysql 格式化而来的。

编辑:获取 json 也有问题,因为我忘记了 php 代码中的标头。

【问题讨论】:

您的代码存在一些问题,即在 fromJson 方法上,但您收到的错误意味着您的 JSON 无效,它可能是某种 html 代码,它在说明你发现它找到了&lt; 作为响应的第一个字符,这当然不是有效的 JSON。请问您是如何检查 JSON 是否有效并显示您的请求代码的? @h8moss 当然,不过说实话,我只是按照文档进行操作。 【参考方案1】:

查看以下代码

void main() 
  var data =     
    "data": [
        
            "Name": "PlayerOne",
            "Data": "\"isOnline\":false"
        ,
        
            "Name": "PlayerTwo",
            "Data": "\"isOnline\":false"
        
    ]
;
  PlayersOnline player = PlayersOnline.fromJson(data);
  
  print(player.data?.first.name); // PlayerOne


class PlayersOnline 
  List<Data>? data;

  PlayersOnline(this.data);

  PlayersOnline.fromJson(Map<String, dynamic> json)
    data = List.from(json['data']).map((e)=>Data.fromJson(e)).toList();
  

  Map<String, dynamic> toJson() 
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.data != null) 
      data['data'] = this.data?.map((v) => v.toJson()).toList();
    
    return data;
  


class Data 
  String? name;
  String? data;

  Data(this.name, this.data);

  Data.fromJson(Map<String, dynamic> json) 
    name = json['Name'];
    data = json['Data'];
  

  Map<String, dynamic> toJson() 
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['Name'] = this.name;
    data['Data'] = this.data;
    return data;
  



未来建设者部分

FutureBuilder<PlayersOnline>(
          future: fetchOnline(),
          builder: (BuildContext context, AsyncSnapshot<PlayersOnline> snapshot) 
            if (snapshot.hasData) 
              return Text(snapshot.data?.first?.name);
             else if (snapshot.hasError) 
              return Text("$snapshot.error");
            

            return const CircularProgressIndicator();
          ,
        )

链接:https://dartpad.dartlang.org/f8c6d477dcbf426a6b5e1bd2fc30bb41

【讨论】:

The argument type 'Future&lt;PlayersOnline&gt;' can't be assigned to the parameter type 'Map&lt;String, dynamic&gt;'. 更新您的futureBuilder 完整代码 当然,但我不太明白如何使用 Future 添加未来属性 请查看更新的未来构建器部分 The getter 'first' isn't defined for the type 'PlayersOnline'.【参考方案2】:
class PlayersOnline 
  List<Data> data;

  PlayersOnline(this.data);

  PlayersOnline.fromJson(Map<String, dynamic> json) 
    if (json['data'] != null) 
      data = new List<Data>();
      json['data'].forEach((v) 
        data.add(new Data.fromJson(v));
      );
    
  

  Map<String, dynamic> toJson() 
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.data != null) 
      data['data'] = this.data.map((v) => v.toJson()).toList();
    
    return data;
  


class Data 
  String name;
  String data;

  Data(this.name, this.data);

  Data.fromJson(Map<String, dynamic> json) 
    name = json['Name'];
    data = json['Data'];
  

  Map<String, dynamic> toJson() 
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['Name'] = this.name;
    data['Data'] = this.data;
    return data;
  

我使用这个网站https://jsontodart.com/ 来生成响应模型。

【讨论】:

以上是关于Flutter JSON 解码的主要内容,如果未能解决你的问题,请参考以下文章

如何在 dart/flutter 中解码复杂的 json?

在 Flutter 中编码/解码复杂的 Json

本文将向您展示如何在 Flutter 中编码/解码 JSON

Flutter json解码_TypeError(类型'List <dynamic>'不是'Map <dynamic,dynamic>'类型的子类型)[关闭]

Flutter json 1处的意外字符

Flutter - 带有 Dart 的通用 json 序列化器