返回顶部
首页 > 资讯 > 移动开发 >flutter中的JSON和序列化方法及使用详解
  • 350
分享到

flutter中的JSON和序列化方法及使用详解

flutterJSON序列化flutterJSON 2023-01-12 12:01:32 350人浏览 泡泡鱼
摘要

目录引言哪种JSON序列化方法适合手动进行序列化使用代码自动序列化Flutter 中是否有 GSON/Jackson/Moshi 之类的序列化类库?使用dart:convert内置库

引言

很难想象一款移动应用程序不需要与WEB服务器通信,也不需要存储结构化数据。在开发一款网络连接的应用程序时,它迟早会需要使用一些JSON。

这里简单介绍一下JSON在flutter中的使用。

Tips:

编码和序列化是将数据结构转换为字符串的同一件事。解码和反序列化是将字符串转换为数据结构的相反过程。然而,序列化通常也指将数据结构转换为更易于阅读的格式的整个过程。

哪种JSON序列化方法适合

这里主要简单介绍两种序列化方式:

  • 手动序列化
  • 使用代码自动序列化

不同的项目复杂度以及用例都不同,对于一些较小的项目或者类似原型的的应用,使用代码生成可能有些大材小用,而对于有很多不同json模型的应用程序,使用手动序列化则除了无聊之外,有可能会产生不必要的问题和麻烦。

手动进行序列化

手动进行json解码说的是使用dart:convert内置的json解码器,通过将原始的json数据传递给jsonDecode()方法,然后在返回的Map<String, dynamic>这个类型的数据中我们可以找到我们想用的数据。不需要别的依赖和其他的设置过程,对于验证一些快速的原型或者小型的项目非常有效。

当项目逐渐变的越来越大的时候,手动解码可能会表现的不尽人意。手动编写解码逻辑可能会变得越来越难以管理,而且变得非常容易出错,如果访问到不存在的字段,或者编写时有拼写错误,代码在运行时就会发生错误。

使用代码自动序列化

对于中大型项目来说,使用代码自动进行序列化可能会是一个比较不错的选择,意味着我们可以使用外部的依赖库来生成我们想要的模版。我们通过设置一些初始化的配置,然后运行一个file watcher从我们的模型类中生成我们想要的代码数据。

比如我们可以使用:json_serializable或者build_value诸如之类的库。

这种方法适用于更大的项目。不需要手工编写模版,并且在编译时会捕捉到访问JSON字段时的拼写错误。

代码生成的缺点是需要一些初始设置。另外,生成的源文件可能会在项目导航器中产生视觉上的混乱。

Flutter 中是否有 GSON/Jackson/Moshi 之类的序列化类库?

GSON以及Jackson都是 Java中用来序列化json的类库。

Moshi则是Kotlin中用来序列化json的类库。

事实上Flutter中并没有类似的库。

因为,这样的库需要使用运行时反射,这在Flutter中是禁用的。运行时反射会干扰【树抖动】treeShaking,Dart已经支持了很长时间。通过treeShaking树抖动,您可以从发布版本中“抖掉”未使用的代码,这可以优化应用程序的大小。

由于反射默认情况下会隐式使用所有代码,因此很难进行treeShaking树抖动。这些工具无法知道哪些部分在运行时未使用,因此冗余代码很难去除。使用反射时,无法轻松优化应用程序大小。

虽然我们不能在Flutter中使用运行时反射,但有些库提供了类似的api,是基于代码生成。

使用dart:convert内置库手动进行序列化

Flutter中的基本JSON序列化非常简单。Flutter有一个内置的dart:convert库,其中包含一个简单的JSON编码器和解码器。

看下面的示例:

{
  "name": "John Smith",
  "email": "john@example.com"
}

使用dart:convert库,我们有两种方法进行序列化。

调用jsonDecode()方法:

Map<String, dynamic> user = jsonDecode(jsonString);
print('Howdy, ${user['name']}!');
print('We sent the verification link to ${user['email']}.');

但是需要注意的是,jsonDecode()方法会返回一个类型为Map<String, dynamic>的类型,这样的话,我们就特别需要注意json中字段的各种类型。

在模型类中序列化JSON

此外,我们可以引入一个简单的模型类(在本例中称为User)来解决前面提到的问题。在User类中,我们可以发现:

  • User.fromJson()构造函数,用于从Map构造新的User实例。
  • toJson()方法,将User实例转换为Map。

使用这种方法,调用代码时可以具有类型安全及编译时异常提醒。如果我们输入了错别字,或者将字段视为int而不是String,应用程序将不会编译,而不会在运行时崩溃。

// user.dart
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:

Map<String, dynamic> userMap = jsonDecode(jsonString);
var user = User.fromJson(userMap);
print('Howdy, ${user.name}!');
print('We sent the verification link to ${user.email}.');

和解码(Decode)相反的是编码(Encode),如果我们想要对User进行编码,我们可以使用jsonEncode()方法:

String json = jsonEncode(user);

使用这种方法,调用代码根本不必担心JSON序列化。然而,模型类仍然必须这样做。在生产应用程序中,我们需要确保序列化工作正常进行。在实际开发过程中,User.fromJson()User.toJson()方法可能都需要进行单元测试以保证结果的正确性。

使用序列化库

尽管有其他库可用,但是这里使用了json_serializable,这是一个自动源代码生成器,可为我们生成json序列化模版。

要在项目中包含json_serializable,需要一个常规依赖项和两个开发依赖项。简而言之,开发依赖项是不包含在我们的应用程序源代码中的依赖项,它们只在开发环境中使用。

我们需要在pubspec.yaml进行如下配置:

**pubspec.yaml**
dependencies:
  # Your other regular dependencies here
  json_annotation: <latest_version>
dev_dependencies:
  # Your other dev_dependencies here
  build_runner: <latest_version>
  json_serializable: <latest_version>

然后在项目根文件夹中运行flutter pub-get以安装依赖。

然后我们以json_serializable的方式创建模型类:

// user.dart
import 'package:json_annotation/json_annotation.dart';
/// This allows the `User` class to access private members in
/// the generated file. The value for this is *.g.dart, where
/// the star denotes the source file name.
part 'user.g.dart';
/// An annotation for the code generator to know that this class needs the
/// JSON serialization logic to be generated.
@JsonSerializable()
class User {
  User(this.name, this.email);
  String name;
  String email;
  /// A necessary factory constructor for creating a new User instance
  /// from a map. Pass the map to the generated `_$UserFromJson()` constructor.
  /// The constructor is named after the source class, in this case, User.
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  /// `toJson` is the convention for a class to declare support for serialization
  /// to JSON. The implementation simply calls the private, generated
  /// helper method `_$UserToJson`.
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

通过这种设置,源代码生成器生成用于对JSON中的nameemail字段进行编码和解码的代码。

如果需要的话,我们还可以定制命名策略,比如,如果API返回带有的对象带有snake_case属性,并且我们希望在模型中使用lowerCamelCase,则可以使用带有name参数的@JsonKey注释:

/// Tell json_serializable that "reGIStration_date_millis" should be
/// mapped to this property.
@JsonKey(name: 'registration_date_millis')
final int registrationDateMillis;

服务器和客户端最好都遵循相同的命名策略。

@JsonSerializable()提供了fieldRename的枚举,用于将dart字段完全转换为JSON键。

修改@JsonSerializable(fieldRename:fieldRename.sake)相当于向每个字段添加@JsonKey(name:“<snake_case>”)

服务器返回的数据是不确定的,所以有必要验证和保护客户端上的数据。

其他常用的@JsonKey注释包括:

/// Tell json_serializable to use "defaultValue" if the JSON doesn't
/// contain this key or if the value is `null`.
@JsonKey(defaultValue: false)
final bool isAdult;
/// When `true` tell json_serializable that JSON must contain the key, 
/// If the key doesn't exist, an exception is thrown.
@JsonKey(required: true)
final String id;
/// When `true` tell json_serializable that generated code should 
/// ignore this field completely. 
@JsonKey(ignore: true)
final String verificationCode;

运行代码生成实用程序

当第一次创建json_serializable类时,会出现类似下图所示的错误。

这些错误完全是正常的,只是因为为模型类生成的代码还不存在。要解决此问题,我们需要运行生成序列化样板的代码生成器。

运行代码生成器有两种方法。

  • 一次性代码生成
  • 持续生成代码

一次性代码生成

通过在项目根目录中运行

flutter pub run build_runner build --delete-conflicting-outputs

我们可以在需要时为模型生成JSON序列化代码。这将触发一次性构建,该构建将遍历源文件,选择相关文件,并为它们生成必要的序列化代码。

虽然这很方便,但如果我们不必每次在模型类中进行更改时都手动运行构建,那就更好了。

持续生成代码

观察者模式使我们的源代码生成过程更加方便。它监听项目文件中的更改,并在需要时自动生成必要的文件。 通过在项目根目录中运行

flutter pub run build_runner watch --delete-conflicting-outputs

可以安全地启动一次观察程序,并让它在一直后台运行。

使用json_serializable模型

要以JSON_serializable的方式解码JSON字符串,实际上不需要对我们之前的代码进行任何更改。

Map<String, dynamic> userMap = jsonDecode(jsonString);
var user = User.fromJson(userMap);

编码也是如此。调用API与之前相同。

String json = jsonEncode(user);

使用json_serializable,我们可以放弃User类中的任何手动json序列化。源代码生成器创建一个名为user.g.dart的文件,该文件具有所有必要的序列化逻辑。我们不再需要编写自动化测试来确保序列化工作,现在库负责确保序列化工作正常。

ps:这里所说的解码和编码,对应的是DecodeEncode

以上就是flutter中的JSON和序列化方法及使用详解的详细内容,更多关于flutter JSON序列化的资料请关注编程网其它相关文章!

--结束END--

本文标题: flutter中的JSON和序列化方法及使用详解

本文链接: https://lsjlt.com/news/177533.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • flutter中的JSON和序列化方法及使用详解
    目录引言哪种JSON序列化方法适合手动进行序列化使用代码自动序列化Flutter 中是否有 GSON/Jackson/Moshi 之类的序列化类库?使用dart:convert内置库...
    99+
    2023-01-12
    flutter JSON序列化 flutter JSON
  • Golang中Json的序列化和反序列化的使用
    目录 JSON:创建格式:基本数据类型序列化:map序列化:切片序列化:反序列化为结构体:反序列化为map:反序列化为切片: JSON: JSON(JavaScr...
    99+
    2024-04-02
  • 实现JSON序列化和反序列化的方法在Golang中
    Golang中JSON序列化和反序列化的实现方式 JSON (JavaScript Object Notation) 是一种常用的数据交换格式,它以文本的形式表示结构化数据。在Golang中,我们可以使用内置...
    99+
    2024-01-29
    Golang 序列化 JSON 实现方式 反序列化
  • Golang中Json的序列化和反序列化怎么使用
    这篇文章主要介绍“Golang中Json的序列化和反序列化怎么使用”,在日常操作中,相信很多人在Golang中Json的序列化和反序列化怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Golang中Js...
    99+
    2023-06-30
  • Python常用标准库详解(pickle序列化和JSON序列化)
    目录常用的标准库序列化模块序列化和反序列化使用场景dumps & loadsdump & loadJSON序列化模块使用场景支持的数据类型JSON和pickle的区别...
    99+
    2024-04-02
  • Redis中的JSON序列化和PHP中的使用
    Redis是一款高效的内存缓存数据库,因其快速的读写能力和支持多种数据结构的特性,已经成为许多开发者常用的工具。而其中的JSON序列化功能,可以方便我们将复杂的数据结构转换成可读性好的JSON格式,实现更好的交互与存储。在这篇文章中,我们将...
    99+
    2023-05-16
    PHP redis JSON序列化
  • Swift 中的 JSON 反序列化示例详解
    目录业界常用的几种方案手动解码方案,如 Unbox(DEPRECATED)阿里开源的 HandyJSON基于 Sourcery 的元编程方案Swift build-in API Co...
    99+
    2024-04-02
  • 如何使用Python中的pickle和JSON进行对象序列化和反序列化
    如何使用Python中的pickle和JSON进行对象序列化和反序列化Python是一种简单而强大的编程语言,其内置了许多有用的库和模块,使开发人员能够快速进行各种任务。其中,pickle和JSON是两个常用的模块,用于对象序列化和反序列化...
    99+
    2023-10-22
    序列化 JSON pickle
  • Redis中的JSON序列化如何使用
    这篇文章主要介绍“Redis中的JSON序列化如何使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Redis中的JSON序列化如何使用”文章能帮助大家解决问题。Redis中的JSON序列化Redi...
    99+
    2023-07-06
  • C#中怎么实现JSON功能及对象的序列化和反序列化
    本篇内容主要讲解“C#中怎么实现JSON功能及对象的序列化和反序列化”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#中怎么实现JSON功能及对象的序列化和反序列化”吧!Newtonsoft.J...
    99+
    2023-06-03
  • java中序列化与反序列化的概念和使用方法介绍
    这篇文章主要介绍“java中序列化与反序列化的概念和使用方法介绍”,在日常操作中,相信很多人在java中序列化与反序列化的概念和使用方法介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java中序列化与反序...
    99+
    2023-06-20
  • Oracle中sequence(序列)使用方法详解
    目录1、create sequence seq_userinfo2、increment  by  13、start with 14、nomaxvalue5、nominvallue6、cach...
    99+
    2023-03-13
    oracle sequence用法 Oracle序列 oracle sequence序列
  • JavaScript语法JSON序列化之stringify实例详解
    目录介绍语法案例valuereplacerspacetoJSON总结介绍 什么是序列化,序列化就是将对象数据转换为可以存储或者传输的过程。在js中,经常使用JSON来进行数据的序列化...
    99+
    2022-11-13
    JavaScript JSON 序列化 stringify JavaScript JSON stringify
  • Go语言基础Json序列化反序列化及文件读写示例详解
    目录概述JSON序列化结构体转JSONmap转JSON切片转JSONJSON反序列化JSON转mapJSON转结构体JSON转切片写JSON文件map写入JSON文件切片写入JSON...
    99+
    2024-04-02
  • 初探Golang中的序列化和反序列化方法
    Golang序列化和反序列化的方法初探 序列化和反序列化是计算机科学中常用的概念,指的是将数据结构或对象转换为一种可在网络上传输或存储的格式,以便在需要时能够重新获得原始数据结构或对象。在Golang中,提供...
    99+
    2024-01-29
    Golang 序列化 反序列化
  • 如何在golang中使用Json序列化
    这篇文章给大家介绍如何在golang中使用Json序列化,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。go自带json库"encoding/json" 官当自带json-iterator号...
    99+
    2023-06-14
  • SpringBoot之Json的序列化和反序列化问题怎么解决
    这篇文章主要讲解了“SpringBoot之Json的序列化和反序列化问题怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringBoot之Json的序列化和反序列化问题怎么解决”吧...
    99+
    2023-07-02
  • JavaScript解析及序列化JSON的示例分析
    这篇文章将为大家详细讲解有关JavaScript解析及序列化JSON的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体如下:JSON 之所以这么流行,是因为 J...
    99+
    2024-04-02
  • 如何使用Python中的序列化和反序列化
    如何使用Python中的序列化和反序列化,需要具体代码示例序列化和反序列化是在数据存储和传输过程中非常重要的概念。在Python中,我们可以使用pickle模块来实现序列化和反序列化操作。本文将详细介绍如何使用Python中的pickle模...
    99+
    2023-10-22
    Python 序列化 反序列化
  • java序列化和serialVersionUID的使用方法实例
    java序列化和serialVersionUID的使用方法实例1、序列化:序列化可以将一个java对象以二进制流的方式在网络中传输并且可以被持久化到数据库、文件系统中,反序列化则是可以把之前持久化在数据库或文件系统中的二进制数据以流的方式读...
    99+
    2023-05-31
    java 序列化 serialversionuid
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作