本文介绍一下Flutter中如何进行json数据的解析。在移动端开发中,请求服务端返回json数据并解析是一个很常见的使用场景。Android原生开发中,有GsonFormat这样的神器,一键生成JavaBean,并利用Gson实现json数据和对象的转化;在React Native中更是得益于直接使用javascript语言,无需对json对象进行解析便可以直接访问属性。那么在Flutter中如何实现对json数据的解析呢?
Flutter采用dart语言进行开发,dart具有很多核心库,其中dart:convert库中内置了json转换器,可以实现将json数据转换成dart对象。简单的使用如下:

import 'dart:convert';

void main() {
// 解析对象
String jsonStr1 = '{"name":"Curry","email":"SC@GSW.com"}';
Map<String, dynamic> map = json.decode(jsonStr1);
print(map['name']); // 解析列表
String jsonStr2 = '[{"name":"Curry"},{"name":"Thompson"}]';
List list = json.decode(jsonStr2);
// 输出列表第一个对象的"name"属性
print(list[0]["name"]);
}

解析json串的方法很简单,直接调用json.decode()即可,但是由于json.decode()方法返回类型为dynamic,因此无法进行类型的检查,编译时不会报错,容易使程序发生错误。采取的做法是像原生开发一样,新建一个model实体类,将json转为实体类对象。生成实体类的方法有以下两种:

方法一.手写实体类

一个简单的实体类实例如下

class User{
final String name;
final String email; User(this.name,this.email); // 命名构造函数
User.fromJson(Map<String, dynamic> json)
: name = json['name'],
email = json['email']; Map<String,dynamic> toJson() =>{
'name':name,
'email':email
};
}

实体类中需要添加两个方法:User.fromJson和toJson,其中,User.fromJson是一个命名构造函数,通过传入的map构造出实体类对象;toJson()方法用于将实体类对象序列化为json字符串。
使用方法如下:

import 'dart:convert';
// 这里需要替换为实体类所在路径
import 'package:json_parse_test/user.dart'; void main() {
// 解析对象
String jsonStr1 = '{"name":"Curry","email":"SC@GSW.com"}';
Map<String, dynamic> map = json.decode(jsonStr1);
User user = User.fromJson(map);
print(user.name); // 解析列表
String jsonStr2 = '[{"name":"Curry"},{"name":"Thompson"}]';
List list= json.decode(jsonStr2);
// 将列表中的第一个对象转换成User对象
print(User.fromJson(list[0]).name); // 将对象序列化为json串
// json.encode()会自动调用实体类中的toJson()
String jsonText = json.encode(user);
print(jsonText);
}

这样就完成了将json转化成实体对象,步骤很简单,但是还有一个问题是,真的每个实体类都要我们自己去手写吗,有没有类似GsonFormat这种一键生成实体类的插件呢。当然是有的,之前从鸿洋大神推荐的Flutter学习资源中偶然发现了一个神奇的网站:
https://javiercbk.github.io/json_to_dart/

 
JSON To Dart.png

可以直接通过json生成实体类代码,仿佛是发现了新大陆,不得不佩服开发出这些快捷工具的大神们,为后面学习的人铺平了道路。网站的操作很简单,一看就会。

方法二.通过json_serializable自动生成

json_serializable是Google官方推荐的一个json序列化库。使用之前需要在pubspec.yaml文件中添加依赖项:
pubspec.yaml

dependencies:
# Your other regular dependencies here
json_annotation: ^2.0.0 dev_dependencies:
# Your other dev_dependencies here
build_runner: ^1.0.0
json_serializable: ^2.0.0

添加之后在项目根目录文件夹中运行flutter packages get (或者在编辑器中点击 “Packages Get”) 以在项目中使用这些新的依赖项。
使用时也是需要新建一个实体类

import 'package:json_annotation/json_annotation.dart';

// user.g.dart通过命令自动生成
part 'user_model.g.dart'; @JsonSerializable()
class User {
// 自定义json字段名对应的属性名,不是必须的
@JsonKey(name: 'userName')
String name;
String email; User(this.name, this.email); factory User.fromJson(Map<String, dynamic> json) =>
_$UserFromJson(json); Map<String, dynamic> toJson() => _$UserToJson(this);
}

需要我们手写的就这些,这时代码会报错,我们需要运行命令来自动生成缺少的文件,有两种生成的方法:

  • 一次性生成
    在项目根目录文件夹下运行
flutter packages pub run build_runner build
  • 持续生成
    在项目根目录文件夹下运行
flutter packages pub run build_runner watch

两者的区别是,一次性生成只执行一次,后面每新建一个实体类都需要重新运行该命令;持续生成会在我们编写代码的过程中根据需要自动生成缺少的文件。
之后解析json的方法和方法一相同

import 'dart:convert';
// 这里需要替换为实体类所在路径
import 'package:json_parse_test/user.dart'; void main() {
// 解析对象
String jsonStr = '{"name":"Curry","email":"SC@GSW.com"}';
Map<String, dynamic> map = json.decode(jsonStr);
User user = User.fromJson(map);
print(user.name);
}

这里关于实体类的生成我找到了做人要简单这位大神写的网页工具,同样是可以很方便地将json转换成实体类代码。

 
json_serializable实体类生成工具

生成代码后点击下载将实体类dart文件下载到本地,之后放到项目中,在项目根目录运行上面提到的生成文件命令即可。
当然也可以通过自已定义模板编写脚本来生成实体类文件,具体做法可以参考《Flutter实战》

总结

Flutter中json的解析分为两步:
1.通过json.decode()将json串转换成dart对象(Map或List)
2.编写实体类(两种方法,手写或自动生成),利用上一步得到的dart对象构造出实体类对象
其实在实际的应用中,我们从服务端返回的响应数据已经通过了网络请求框架的封装,比如很常用的Dio,我们可以直接从返回的响应中获取到dart对象,省去了第一步,直接转化成实体类对象即可。

链接:https://www.jianshu.com/p/830ecb047d3d

Flutter 中 JSON 解析的更多相关文章

  1. IOS中Json解析的四种方法

    作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有的json代码格式比较混乱,可以使用此“http://www.bejson.com/”网站来进行JSON格式化校验 ...

  2. Android 中Json解析的几种框架(Gson、Jackson、FastJson、LoganSquare)使用与对比

    介绍 移动互联网产品与服务器端通信的数据格式,如果没有特殊的需求的话,一般选择使用JSON格式,Android系统也原生的提供了JSON解析的API,但是它的速度很慢,而且没有提供简介方便的接口来提高 ...

  3. iOS 中json解析数据出现中文乱码的问题

    一般服务器的编码格式都是UTF8,这样通过json解析下来的的数据,一般中文是不会出现乱码,但是如果服务器的编码格式不是UTF8,通过json解析的数据中的中文容易出现luan乱码,怎么解决这个问题呢 ...

  4. golang struct 定义中json``解析说明

    在代码学习过程中,发现struct定义中可以包含`json:"name"`的声明,所以在网上找了一些资料研究了一下 package main import ( "enco ...

  5. 【转】IOS中Json解析的四种方法

    原文网址:http://blog.csdn.net/enuola/article/details/7903632 作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有 ...

  6. Java中Json解析

    首先准备一个JSON格式的字符串 * String JsonStr = "{object:{persons:" + "[{name:'呵呵',image:'http:// ...

  7. iOS中JSON解析三方库的比较

    网络数据解析框架 1.  JsonModel 一个 JSON 模型转换库,有着比较简洁的接口.Model 需要继承自 JSONModel. 2.  yyModel yyModel比较轻量(算上.h 只 ...

  8. ios中json解析出现的null问题

    http://my.oschina.net/iq19900204/blog/408034 在iOS开发过程中经常需要与服务器进行数据通讯,Json就是一种常用的高效简洁的数据格式. 问题现象 但是几个 ...

  9. iOS中json解析出现的null,nil,NSNumber的问题

    在iOS开发过程中经常需要与服务器进行数据通讯,Json就是一种常用的高效简洁的数据格式. 问题现象 但是几个项目下来一直遇到一个坑爹的问题,程序在获取某些数据之后莫名崩溃.其实很早就发现了原因:由于 ...

随机推荐

  1. 7.01-beautiful_soup3

    # pip install beautifulsoup4 from bs4 import BeautifulSoup html_doc = """ <html> ...

  2. sqlite线程模式的设置

    (1)编译阶段 这几种模式可以通过参数SQLITE_THREADSAFE在编译阶段指定,可以取值0,1,2,默认是1.这三种取值的含义如下: 0:单线程模式,即内部不做mutex保护,多线程运行sql ...

  3. HTTP请求报文解剖

    转自:https://www.iteye.com/topic/1124408 HTTP请求报文由3部分组成(请求行+请求头+请求体): 下面是一个实际的请求报文: ①是请求方法,GET和POST是最常 ...

  4. [Git] Git操作命令

    基础操作 git配置 git config --global user.name "Your Name" git config --global user.email " ...

  5. [POI2012]SZA-Cloakroom

    嘟嘟嘟 一道比较有意思的dp. 这题关键在于状态的设计.如果像我一样令\(dp[i][j]\)表示选到第\(i\)个物品,\(\sum c\)能都等于\(j\)的话,那就是\(O(qnk)\)了,怒拿 ...

  6. P1577 切绳子(二分)

    思路:先来分析一下数据范围,是1e4个数据,但是,是double类型,结果不超过0.01那么在绳子最大的情况下,单纯的找正确答案暴力的话就是1e7的时间复杂度,再乘上1e4的数据,这样肯定不行.那么很 ...

  7. scipy 安装错误及解决

    pip 安装 scipy 时,因为是编译安装,所以如果缺少一些编译库,会报很多错误,以下总结可能缺失的安装包: sudo apt-get install gfortran sudo apt-get i ...

  8. Libinput 1.13 RC2发布

    Red Hat的Peter Hutterer周四宣布发布libinput 1.13 RC2,作为X.Org和Wayland Linux系统使用此输入处理库的最新测试版本. Libinput 1.13将 ...

  9. Vscode的python配置(macOS)

    _ 1. Vscode是一款开源的跨平台编辑器.默认情况下,vscode使用的语言为英文(en),以下步骤改为中文 打开vscode工具,使用快捷键组合[Cmd+Shift+p],在搜索框中输入“co ...

  10. odoo11 安装python ldap

    最近在研究odoo11使用ldap登录的问题,本来自己想着怎么开发,无意间在odoo11代码中看到auth_ldap的模块,原来框架已经考虑到了这个,简单研究了代码之后,理解了其大概的登录处理过程,此 ...