Flutter JSON序列化插件json_serializable的使用

发布于 1周前 作者 yuanlaile 来自 Flutter

Flutter JSON序列化插件json_serializable的使用

简介

json_serializable 是一个用于处理JSON序列化的Dart Build System构建器。它通过查找注解了 package:json_annotation 中类成员来生成代码。

Setup

为了配置你的项目以使用最新版本的 json_serializable,可以参考官方示例

示例

假设有一个名为 example.dart 的库,其中包含一个被 JsonSerializable 注解的 Person 类:

import 'package:json_annotation/json_annotation.dart';

part 'example.g.dart';

@JsonSerializable()
class Person {
  /// The generated code assumes these values exist in JSON.
  final String firstName, lastName;

  /// The generated code below handles if the corresponding JSON value doesn't
  /// exist or is empty.
  final DateTime? dateOfBirth;

  Person({required this.firstName, required this.lastName, this.dateOfBirth});

  /// Connect the generated [_$PersonFromJson] function to the `fromJson`
  /// factory.
  factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);

  /// Connect the generated [_$PersonToJson] function to the `toJson` method.
  Map<String, dynamic> toJson() => _$PersonToJson(this);
}

构建后会创建相应的部分文件 example.g.dart

part of 'example.dart';

Person _$PersonFromJson(Map<String, dynamic> json) => Person(
      firstName: json['firstName'] as String,
      lastName: json['lastName'] as String,
      dateOfBirth: json['dateOfBirth'] == null
          ? null
          : DateTime.parse(json['dateOfBirth'] as String),
    );

Map<String, dynamic> _$PersonToJson(Person instance) => <String, dynamic>{
      'firstName': instance.firstName,
      'lastName': instance.lastName,
      'dateOfBirth': instance.dateOfBirth?.toIso8601String(),
    };

运行代码生成器

添加注解后,需要运行代码生成器以生成缺失的 .g.dart 文件。在包目录中运行以下命令:

dart run build_runner build

注解值

主要注解包括:

  • JsonSerializable:用于类,生成 fromJsontoJson 方法。
  • JsonKey:用于字段,提供更细粒度的配置。
  • JsonEnum:用于枚举类型,指定编码逻辑。
  • JsonValue:用于枚举值,指定编码后的值。

枚举支持

enum StatusCode {
  @JsonValue(200)
  success,
  @JsonValue(301)
  movedPermanently,
  @JsonValue(302)
  found,
  @JsonValue(500)
  internalServerError,
}

@JsonEnum(valueField: 'code')
enum StatusCodeEnhanced {
  success(200),
  movedPermanently(301),
  found(302),
  internalServerError(500);

  const StatusCodeEnhanced(this.code);
  final int code;
}

支持的类型

json_serializable 内置支持许多常见的 Dart 核心库类型,如 BigInt, bool, DateTime, double, Duration, Enum, int, Iterable, List, Map, num, Object, Record, Set, String, Uri

对于集合类型(如 Iterable, List, Map, Record, Set),它们可以包含上述所有类型的值。

自定义类型和自定义编码

如果要使用不支持的类型或自定义编码/解码,有几种方法:

  1. 为类型添加 fromJson 构造函数和 toJson() 方法
  2. 使用 JsonKey.toJsonJsonKey.fromJson 属性
  3. 实现 JsonConverter 并注解字段或类

例如:

@JsonSerializable()
class Sample4 {
  Sample4(this.value);

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

  @EpochDateTimeConverter()
  final DateTime value;

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

class EpochDateTimeConverter implements JsonConverter<DateTime, int> {
  const EpochDateTimeConverter();

  @override
  DateTime fromJson(int json) => DateTime.fromMillisecondsSinceEpoch(json);

  @override
  int toJson(DateTime object) => object.millisecondsSinceEpoch;
}

构建配置

除了设置关联注解类的参数外,还可以通过 build.yaml 配置代码生成:

targets:
  $default:
    builders:
      json_serializable:
        options:
          any_map: false
          checked: false
          constructor: ""
          create_factory: true
          create_field_map: false
          create_json_keys: false
          create_per_field_to_json: false
          create_to_json: true
          disallow_unrecognized_keys: false
          explicit_to_json: false
          field_rename: none
          generic_argument_factories: false
          ignore_unannotated: false
          include_if_null: true

以上是 json_serializable 插件的基本用法和配置说明,希望对您有所帮助!


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

1 回复

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


当然,下面是一个关于如何在Flutter中使用json_serializable插件进行JSON序列化和反序列化的详细代码示例。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加json_annotationbuild_runner的依赖:

dependencies:
  flutter:
    sdk: flutter
  json_annotation: ^4.0.1  # 请确保使用最新版本

dev_dependencies:
  build_runner: ^2.0.4  # 请确保使用最新版本

2. 创建数据模型

接下来,创建一个数据模型类,并使用@JsonSerializable()注解。然后,生成所需的代码。

// models/user.dart
import 'package:json_annotation/json_annotation.dart';

part 'user.g.dart';

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

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

  // 调用生成的fromJson方法
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);

  // 调用生成的toJson方法
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

3. 生成序列化代码

在终端中运行以下命令以生成json_serializable所需的代码:

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

这个命令会在你的项目中生成一个user.g.dart文件,其中包含fromJsontoJson方法的实现。

4. 使用序列化和反序列化

现在你可以在你的Flutter应用中使用这些方法来序列化和反序列化JSON数据。

import 'package:flutter/material.dart';
import 'models/user.dart';

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

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

class UserDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 示例JSON数据
    String jsonString = '{"name": "John Doe", "age": 30, "email": "john.doe@example.com"}';

    // 反序列化JSON数据
    User user = User.fromJson(jsonDecode(jsonString));

    // 打印用户对象
    print('User Name: ${user.name}');
    print('User Age: ${user.age}');
    print('User Email: ${user.email}');

    // 序列化用户对象为JSON
    Map<String, dynamic> userJson = user.toJson();
    String serializedJsonString = jsonEncode(userJson);

    // 打印序列化后的JSON字符串
    print('Serialized JSON: $serializedJsonString');

    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('User Name: ${user.name}'),
        Text('User Age: ${user.age}'),
        Text('User Email: ${user.email}'),
      ],
    );
  }
}

注意事项

  1. 确保你已经在项目中正确添加了依赖,并运行了flutter pub get
  2. 在修改数据模型类后,需要重新运行flutter pub run build_runner build命令来生成新的序列化代码。
  3. jsonDecodejsonEncode是Flutter标准库中的函数,用于将JSON字符串解码为Map,以及将Map编码为JSON字符串。

这样,你就可以在Flutter中使用json_serializable插件进行JSON数据的序列化和反序列化了。

回到顶部