Flutter数据序列化插件serializable的使用

Flutter数据序列化插件serializable的使用

概述

本库从使用@serializable@Serializable()标注的类生成一个可序列化的类。

Build Status

开始使用

以下是使用serializable插件的步骤:

  1. 创建一个新的Dart项目。

  2. pubspec.yaml文件中添加依赖项。

dependencies:
  #...
  serializable: any   # 更改为最新的依赖版本
  #...

dev_dependencies:
  #...
  build_runner: any   # 更改为最新的依赖版本
  #...
  1. 创建一个名为models.dart的文件,并添加以下代码:
library example.models;

import 'package:serializable/serializable.dart';

part 'models.g.dart';

class SimpleType {
  String id;
  String name;

  SimpleType(this.id, this.name);
}

@serializable
class Person extends SerializableMap with _$PersonSerializable {
  int? id;
  String? name;
  var someDynamic;
  Map? someMap;
  Map<String, int>? otherMap;

  Address? address;

  List<Address>? otherAddresses;

  static final Map<String, SimpleType> list = {
    'minutes': SimpleType('58c42d14f17f33ec6e2020ad', 'minutes'),
    'hours': SimpleType('58c42d26f17f33ec6e2020ae', 'hours'),
    'percent': SimpleType('58c42d4bf17f33ec6e2020b3', 'percent')
  };
}

@serializable
class Address extends SerializableMap with _$AddressSerializable {
  int? id;
  String? street;
  String? zip;
  String? city;
  String? state;
}

@serializable
class ClassWithMethod extends SerializableMap with _$ClassWithMethodSerializable {
  void sayHello(String name) {
    print('Hello $name!');
  }
}
  1. 创建一个名为main.dart的文件,并添加以下代码:
import 'dart:convert';

import 'models.dart';

void main() {
  var p1 = Person()
    ..id = 1
    ..name = 'person 1';

  // 可以使用方括号符号来获取/设置属性

  print("p1['id']: ${p1['id']}"); // 打印 `p1['id']: 1`
  print("p1['name']: ${p1['name']}"); // 打印 `p1['name']: person 1`
  p1['id'] = 1; // 将 `p1.id` 设置为 `1`
  p1['name'] = 'person 1'; // 将 `p1.name` 设置为 `person 1`

  try {
    p1['no_existing'];
  } catch (e) {
    print(e); // 打印 `FieldNotFoundException: The key "no_existing" doesn't exist on class "Person"`
  }

  // 可以使用它将对象转换为/从 Map

  print('p1.toMap(): ${p1.toMap()}'); // 打印 `{id: 1, name: person 1}`
  var p2 = Person()
    ..fromMap({"id": 2, "name": "person 2", 'address': Address()..fromMap({'id': 1})});
  print('p2: {id: ${p2.id}, name: ${p2.name}, address.id: ${p2.address?.id}}'); // 打印 `p2: {id: 2, name: person 2, address.id: 1}`

  var p3 = Person()
    ..fromMap({
      "id": 3,
      "name": "person 3",
      'address': Address()..fromMap({'id': 3}),
      'otherAddresses': [{'id': 4, 'street': 'street 4'}].map((e) => Address()..fromMap(e)).toList()
    });
  print('p3: {id: ${p3.id}, name: ${p3.name}, address.id: ${p3.address?.id}, otherAddresses[0].street:'
      ' ${p3.otherAddresses?[0].street}}'); // 打印 `p3: {id: 3, name: person 3, address.id: 3}`

  // 可以使用 `dart:convert` 库直接将对象转换为/从JSON

  print('p1: ${jsonEncode(p1)}'); // 打印 `p1: {"id":1,"name":"person 1"}`

  var p4Map = jsonDecode('{"id": 3, "name": "person 3"}');
  var p4 = Person()
    ..fromMap(p4Map);

  print('p4: {id: ${p4.id}, name: ${p4.name}}'); // 打印 `p4: {id: 4, name: person 4}`

  ClassWithMethod()['sayHello']('world'); // 打印 `Hello world!`
}
  1. 运行 pub run build_runner build 这将会生成bin/models.g.dart文件,并包含以下代码:
// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'models.dart';

// **************************************************************************
// SerializableGenerator
// **************************************************************************

mixin _$PersonSerializable on SerializableMap {
  int? get id;
  String? get name;
  dynamic get someDynamic;
  Map<dynamic, dynamic>? get someMap;
  Map<String, int>? get otherMap;
  Address? get address;
  List<Address>? get otherAddresses;
  set id(int? v);
  set name(String? v);
  set someDynamic(dynamic v);
  set someMap(Map<dynamic, dynamic>? v);
  set otherMap(Map<String, int>? v);
  set address(Address? v);
  set otherAddresses(List<Address>? v);

  operator [](Object? __key) {
    switch (__key) {
      case 'id':
        return id;
      case 'name':
        return name;
      case 'someDynamic':
        return someDynamic;
      case 'someMap':
        return someMap;
      case 'otherMap':
        return otherMap;
      case 'address':
        return address;
      case 'otherAddresses':
        return otherAddresses;
    }
    throwFieldNotFoundException(__key, 'Person');
  }

  operator []=(Object? __key, __value) {
    switch (__key) {
      case 'id':
        id = __value;
        return;
      case 'name':
        name = __value;
        return;
      case 'someDynamic':
        someDynamic = __value;
        return;
      case 'someMap':
        someMap = fromSerialized(__value, () => Map<dynamic, dynamic>());
        return;
      case 'otherMap':
        otherMap = fromSerialized(__value, () => Map<String, int>());
        return;
      case 'address':
        address = fromSerialized(__value, () => Address());
        return;
      case 'otherAddresses':
        otherAddresses = fromSerialized(__value,
            [() => List<Address>.empty(growable: true), () => Address()]);
        return;
    }
    throwFieldNotFoundException(__key, 'Person');
  }

  Iterable<String> get keys => const [
        'id',
        'name',
        'someDynamic',
        'someMap',
        'otherMap',
        'address',
        'otherAddresses'
      ];
}

mixin _$AddressSerializable on SerializableMap {
  int? get id;
  String? get street;
  String? get zip;
  String? get city;
  String? get state;
  set id(int? v);
  set street(String? v);
  set zip(String? v);
  set city(String? v);
  set state(String? v);

  operator [](Object? __key) {
    switch (__key) {
      case 'id':
        return id;
      case 'street':
        return street;
      case 'zip':
        return zip;
      case 'city':
        return city;
      case 'state':
        return state;
    }
    throwFieldNotFoundException(__key, 'Address');
  }

  operator []=(Object? __key, __value) {
    switch (__key) {
      case 'id':
        id = __value;
        return;
      case 'street':
        street = __value;
        return;
      case 'zip':
        zip = __value;
        return;
      case 'city':
        city = __value;
        return;
      case 'state':
        state = __value;
        return;
    }
    throwFieldNotFoundException(__key, 'Address');
  }

  Iterable<String> get keys => const ['id', 'street', 'zip', 'city', 'state'];
}

mixin _$ClassWithMethodSerializable on SerializableMap {
  void sayHello(String name);

  operator [](Object? __key) {
    switch (__key) {
      case 'sayHello':
        return sayHello;
    }
    throwFieldNotFoundException(__key, 'ClassWithMethod');
  }

  operator []=(Object? __key, __value) {
    switch (__key) {}
    throwFieldNotFoundException(__key, 'ClassWithMethod');
  }

  Iterable<String> get keys => const [];
}
  1. 最后,运行bin/main.dart文件。 如果一切正常,你将在控制台看到以下输出:
p1['id']: 1
p1['name']: person 1
FieldNotFoundException: The key "no_existing" doesn't exist on class "Person"
p1.toMap(): {id: 1, name: person 1}
p2: {id: 2, name: person 2}
p1: {"id":1,"name":"person 1"}
p3: {id: 3, name: person 3}

更多关于Flutter数据序列化插件serializable的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据序列化插件serializable的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter开发中,json_serializable 是一个流行的数据序列化插件,它允许你将Dart对象与JSON数据进行互转。虽然你提到的是 serializable,但通常我们使用的是 json_serializable。下面是如何在Flutter项目中使用 json_serializable 的详细步骤,包括相关的代码示例。

步骤 1: 添加依赖

首先,在你的 pubspec.yaml 文件中添加 json_serializable 及其依赖项:

dependencies:
  flutter:
    sdk: flutter

dev_dependencies:
  build_runner: ^2.1.4
  json_serializable: ^6.1.4

步骤 2: 创建数据模型

接下来,创建一个数据模型类,并使用 @JsonSerializable() 注解标记它。此外,还需要导入 json_annotation 包。

import 'package:json_annotation/json_annotation.dart';

part 'user_model.g.dart'; // 这行很重要,指示生成代码的文件

@JsonSerializable()
class User {
  final String name;
  final int age;

  User({required this.name, required this.age});

  // 从JSON生成User对象
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);

  // 将User对象转换为JSON
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

步骤 3: 生成代码

在项目的根目录下运行以下命令来生成 *.g.dart 文件:

flutter pub run build_runner build

这将为 User 类生成必要的 fromJsontoJson 方法。

步骤 4: 使用序列化和反序列化

现在你可以使用生成的 fromJsontoJson 方法来序列化和反序列化数据了。

void main() {
  // 创建一个User对象
  User user = User(name: 'John Doe', age: 30);

  // 将User对象转换为JSON
  Map<String, dynamic> userJson = user.toJson();
  print('User to JSON: $userJson');

  // 从JSON生成User对象
  User newUser = User.fromJson(userJson);
  print('JSON to User: ${newUser.name}, Age: ${newUser.age}');
}

完整示例

将上述步骤整合到一起,你的项目结构可能如下所示:

pubspec.yaml

name: flutter_app
description: A new Flutter project.

version: 1.0.0+1

environment:
  sdk: ">=2.12.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

dev_dependencies:
  build_runner: ^2.1.4
  json_serializable: ^6.1.4

flutter:
  uses-material-design: true

lib/main.dart

import 'package:flutter/material.dart';
import 'user_model.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter JSON Serialization Demo'),
        ),
        body: Center(
          child: DemoWidget(),
        ),
      ),
    );
  }
}

class DemoWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 创建一个User对象
    User user = User(name: 'John Doe', age: 30);

    // 将User对象转换为JSON
    Map<String, dynamic> userJson = user.toJson();
    print('User to JSON: $userJson');

    // 从JSON生成User对象
    User newUser = User.fromJson(userJson);
    print('JSON to User: ${newUser.name}, Age: ${newUser.age}');

    return Text('Check console for serialization/deserialization output.');
  }
}

lib/user_model.dart

import 'package:json_annotation/json_annotation.dart';

part 'user_model.g.dart';

@JsonSerializable()
class User {
  final String name;
  final int age;

  User({required this.name, required this.age});

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);

  Map<String, dynamic> toJson() => _$UserToJson(this);
}

运行 flutter pub run build_runner build 后,你的项目将包含所需的 user_model.g.dart 文件,并且你可以在 DemoWidget 中看到序列化和反序列化的输出。

这样,你就成功地在Flutter项目中使用 json_serializable 插件进行数据序列化了。

回到顶部