Flutter 中 JSON 解析
本文介绍一下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生成实体类代码,仿佛是发现了新大陆,不得不佩服开发出这些快捷工具的大神们,为后面学习的人铺平了道路。网站的操作很简单,一看就会。
方法二.通过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转换成实体类代码。

生成代码后点击下载将实体类dart文件下载到本地,之后放到项目中,在项目根目录运行上面提到的生成文件命令即可。
当然也可以通过自已定义模板编写脚本来生成实体类文件,具体做法可以参考《Flutter实战》。
总结
Flutter中json的解析分为两步:
1.通过json.decode()将json串转换成dart对象(Map或List)
2.编写实体类(两种方法,手写或自动生成),利用上一步得到的dart对象构造出实体类对象
其实在实际的应用中,我们从服务端返回的响应数据已经通过了网络请求框架的封装,比如很常用的Dio,我们可以直接从返回的响应中获取到dart对象,省去了第一步,直接转化成实体类对象即可。
链接:https://www.jianshu.com/p/830ecb047d3d
Flutter 中 JSON 解析的更多相关文章
- IOS中Json解析的四种方法
作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有的json代码格式比较混乱,可以使用此“http://www.bejson.com/”网站来进行JSON格式化校验 ...
- Android 中Json解析的几种框架(Gson、Jackson、FastJson、LoganSquare)使用与对比
介绍 移动互联网产品与服务器端通信的数据格式,如果没有特殊的需求的话,一般选择使用JSON格式,Android系统也原生的提供了JSON解析的API,但是它的速度很慢,而且没有提供简介方便的接口来提高 ...
- iOS 中json解析数据出现中文乱码的问题
一般服务器的编码格式都是UTF8,这样通过json解析下来的的数据,一般中文是不会出现乱码,但是如果服务器的编码格式不是UTF8,通过json解析的数据中的中文容易出现luan乱码,怎么解决这个问题呢 ...
- golang struct 定义中json``解析说明
在代码学习过程中,发现struct定义中可以包含`json:"name"`的声明,所以在网上找了一些资料研究了一下 package main import ( "enco ...
- 【转】IOS中Json解析的四种方法
原文网址:http://blog.csdn.net/enuola/article/details/7903632 作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有 ...
- Java中Json解析
首先准备一个JSON格式的字符串 * String JsonStr = "{object:{persons:" + "[{name:'呵呵',image:'http:// ...
- iOS中JSON解析三方库的比较
网络数据解析框架 1. JsonModel 一个 JSON 模型转换库,有着比较简洁的接口.Model 需要继承自 JSONModel. 2. yyModel yyModel比较轻量(算上.h 只 ...
- ios中json解析出现的null问题
http://my.oschina.net/iq19900204/blog/408034 在iOS开发过程中经常需要与服务器进行数据通讯,Json就是一种常用的高效简洁的数据格式. 问题现象 但是几个 ...
- iOS中json解析出现的null,nil,NSNumber的问题
在iOS开发过程中经常需要与服务器进行数据通讯,Json就是一种常用的高效简洁的数据格式. 问题现象 但是几个项目下来一直遇到一个坑爹的问题,程序在获取某些数据之后莫名崩溃.其实很早就发现了原因:由于 ...
随机推荐
- FinalShell安装
Mac版安装路径/Applications/finalshelldata Linux版安装路径/usr/lib/finalshelldata 注意:1.FinalShell运行需要java或者jdk支 ...
- java中的多态是怎么体现的
多态是父类的引用指向了自己的子类对象. 当调用方法时,会根据对象去调用方法,先在子类中找,没有就去父类中找 总结:成员变量是在编译阶段绑定的,方法时在运行阶段绑定的.属性不能重写,方法可以重写. pu ...
- C#中webbrowser与javascript(js)交互的方法
今天在做一个项目的时候需要用c#搞一个webbrowser,然后有些地方还需要与js交互.所以就查了一下资料,发现很多博客提到了但是却没有说下具体的操作.所以我就写一下. 开发环境是Visual St ...
- 【转】编写微信聊天机器人4《聊天精灵WeChatGenius》:实时获取到微信聊天消息,hook数据库插入操作。
接上篇,使用Xposed来hook微信,找到微信进程:https://blog.csdn.net/weixin_42127613/article/details/81839537 既然已经找到了微信进 ...
- Java 定义静态list
private final static List<String> imgList = Arrays.asList("group1/M00/0B/B0/rBGl-lvr7vWAN ...
- day04 if判断、while条件循环、for迭代器循环部分使用举例
一:if判断 1.成绩>=90,那么:优秀 如果成绩>=80且<90,那么:良好 如果成绩>=70且<80,那么:普通 其 ...
- node.js之Cookie
最近还是用node.js比较多,今天正好遇见一个问题,还是关于Cookie. node.js中如何实现cookie(以express框架为例): "use strict"; var ...
- 初学Python——装饰器
一.什么是装饰器 当我们做好一个产品之后,需要对它进行不断地维护,对某些函数增加一些功能.这个时候如果去修改源代码将是非常不合适的.(原因:1.原则上已经写好的函数尽量不去修改它,因为一旦修改可能会导 ...
- 图片完全填充CardView区域
在Android开发中,使用CardView来显示我们需要展示的图片,但是有时候显示出来的图片并没有填充整个CardView区域,为了让需要展示的图片填充整个CardView区域,只需要在ImageV ...
- 开源框架bboss单点登录demo跑起来
目前公司新项目要使用一个开源框架bboss的单点登录功能,要将此功能整合到新系统中去,所以我就学习了一下. 首先,进入这个bboss框架作者的博客中,找到相应的session共享,单点登录的博文,看了 ...