flutter json数据处理

本文涉及的业务场景

只要咱们的app不是单机的,那么必然涉及到远程服务器数据请求。在flutter中,发起请求已经有现成的包dio了,使用起来也很是简练方便,如仍是不是很了解,能够点击查看dio的详细文档javascript

发起请求,拿到服务端返回的json数据后,接下来的步骤是怎么样的。flutter(应该说是Dart)可不像javascript那样,对json天生友好。这就是本文要讲的主要内容。你将会学到:html

  • flutter项目json数据处理的详细步骤和踩坑提醒
  • json_serializable环节,命令行+工具,帮你自动化生成相关代码,无需手敲,无需手敲(重要的事情说两遍)
  • 数据和源码都为你准备稳当,无需手敲(即便小白,也能够轻松上手)

json数据读取和处理

请求回来数据后,下一步必然就是读取其中的数据信息,而后依此进行界面展现和逻辑处理了。java

若是返回来的是简单的数据,并且业务逻辑也很简单,那么其实处理方式也能够简单化,例如服务端返回数据以下:git

{
        code: 200,
        message: null,
        value: true
    }
复制代码

那么,你甚至能够这么处理:github

if (jsonStr.indexOf('true') != -1) {
        // do something
    }
复制代码

总结的说,在这种场景下面,使用正则表达式匹配或者简单字符串处理逻辑,进行简单快速的实现,也不失为一种好方法。正则表达式

json反序列化

可是,当数据结构足够复杂(例如:点击查看复杂数据示例),那么上述的方式显然就有点捉襟见肘了。shell

这个时候,就该轮到本文要讲述的重点,json反序列化上场了。关于序列化和反序列化,能够上网查一下,有不少资料(实在不想查,好吧,这里有现成的,点击序列化凑合着看一下吧...)。json

在本文描述的业务场景下面,也能够简单理解为,咱们要作的,就是把经过dio拿到的服务端json字符串数据,转换为对象,而后就能够愉快的访问该对象中的字段值了。api

主要的步骤有两个:bash

  • json字符串转换为Map对象
  • 使用json_serializable进行反序列化

具体步骤以下:

  • 添加依赖

参考下面代码,往pubspec.yaml文件中添加json_annotationjson_serializablebuild_runner包。

dependencies:
  flutter:
    sdk: flutter
  
  json_annotation: ^3.0.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  
  json_serializable: ^3.2.0
  build_runner: ^1.6.5
复制代码

添加完,记得flutter packages get

  • 使用在线代码生成工具把json生成dart代码,代码命名为xxxx.dart(文件一,会在下文的代码中引用到)copy到项目中

若是你已经看过其余相关文章,颇有多是要你根据json数据写一个dart的实体类,其实,也能够的,选择你喜欢方式就好了。本文推荐工具生成,方便快捷,不易出错,哈哈。。。

若是,你还没来得及准备好试验的json数据,点击本文为你提供的数据示例,copy到工具中,愉快的玩耍吧。

  • 在当前项目的目录下运行flutter packages pub run build_runner build,命令执行完成,根据刚刚的xxxx.dart生成xxxx.g.dart(该文件生成后不要手动改,也无需引用,放着不动就是了)
  • 开始编码
import 'dart:convert';
import 'package:xxxxxxx/xxxx.dart'; //引入上面说起的文件一

String jsonStr = '{"value":1}'; //你要进行反序列化的json字符串
Map<String ,dynamic> map = json.decode(jsonStr); //先转成Map
           
MyObject obj = MyObject.fromJson(map); //假设class名为MyObject,这个根据实际状况调整
print(obj.value);
复制代码

到此,基本就完成了数据的反序列化。上述代码中,主要是两个步骤:

  • String to Map
  • Map to MyObject

MyObject即引入的“文件一”中的类名,可根据实际状况进行调整。

也可能你会有疑问,既然原生已经提供了String to Map,那么只作到这一步,而后使用map对象进行接下来的coding,ok吗。

其实,也是能够的,只是。。。,下面举个列子对比一下,便一目了然了。以该数据示例为例,下面两行代码,访问的字段是同样的:

print(homePageList.value[0].modules[0].items[1].title);

print(map.entries.elementAt(2).value[0].entries.elementAt(5).value[0].entries.elementAt(11).value[1].entries.elementAt(0).value);
复制代码

不知你喜欢哪一种方式呢。。。

复杂不规则数据处理

按照上述的具体步骤,基本能够处理大部分的规则数据了,可是当你以数据示例为数据源,一步一步操做coding完,访问其中某些字段的值时,意想不到的事情发生了:

print(homePageList.value[0].modules[0].items[1].title); //正常打印

print(homePageList.value[0].modules[2].items[0].name); // 报错
复制代码

报错信息:

The following NoSuchMethodError was throw building BlockRowFrame(dirty):
Class 'Modules' has no instance getter 'title'.
...
复制代码

The following NoSuchMethodError was throw building BlockRowFrame(dirty)

这是由于,数据每一项的结构不一致致使的。数据示例中,字段name在前两个modulesitems元素中并无,而在第三个modulesitems元素中,却有了。

遇到这种状况,只须要在用工具生成的"文件一"中对应的class,手动添加上对应的字段代码,而后再从新运行一次flutter packages pub run build_runner build --delete-conflicting-outputs即可。

到此,关于flutter json数据处理分享就讲完了。码字不易,以为此文对你有帮助的,麻烦点个赞鼓励鼓励。

后记

若是还有不清楚的地方。。。

不要紧,源码伺候,点击flutter_examples访问对应的github项目,其中的“json格式请求结果反序列化与使用(dio & json_serializable demo)”实例,就是本文的代码实现!

相关文章
相关标签/搜索