【Flutter 必备插件】JSON 序列化

2026-01-30
【Flutter 必备插件】JSON 序列化 关注 作者 关注 作者 关注 作者 关注 作者 2025/07/16 15:19

在现代移动应用开发中,与服务器进行数据交互是必不可少的功能。JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,因其易读性、简洁性和广泛支持性,已成为前后端通信的事实标准。在 Flutter 开发中,我们经常需要将 JSON 数据转换为 Dart 对象(反序列化),或将 Dart 对象转换为 JSON 数据(序列化)。 xxxx

什么是 json_serializable

json_serializable 是一个基于Dart构建系统的代码生成库,它通过注解驱动的方式,自动为你的模型类生成序列化代码。它的核心优势在于: 海外华人视频网 爱壹帆 小宝影院 aiyifan电影 楼凤阁

  • 类型安全:生成的代码完全类型安全,避免了手动转换可能带来的类型错误
  • 减少样板代码:自动生成重复的序列化代码,提高开发效率
  • 可维护性:模型变更时,只需重新生成代码即可同步更新序列化逻辑
  • 灵活性:提供多种配置选项处理各种复杂场景

环境配置

dependencies:
  flutter:
    sdk: flutter
  json_annotation: ^4.9.0   # 提供必要的注解
 
dev_dependencies:
  build_runner: ^2.5.4      # 代码生成工具
  json_serializable: ^6.9.5 # 序列化代码生成器

实战

基本使用方法

1. 创建基础模型类

import 'package:json_annotation/json_annotation.dart';

// 这个文件是自动生成的,必须声明part
part 'token.g.dart';

// 核心注解,表示这个类需要生成序列化代码
@JsonSerializable()
class Token {
  final String accessToken;
  final int expiresIn;
  final String refreshToken;

  Token({required this.accessToken, required this.expiresIn, required this.refreshToken});

  /// 从 JSON 映射创建 Token 实例的工厂构造函数
  factory Token.fromJson(Map<String, dynamic> json) => _$TokenFromJson(json);

  /// 将 Token 实例转换为 JSON 映射的方法
  Map<String, dynamic> toJson() => _$TokenToJson(this);
}

关键点说明: xxx xxxxxx ifun 电影爱壹帆 小宝影院 ifun 约炮

  1. part ‘token.g.dart’ 声明表示这个文件将包含自动生成的代码
  2. @JsonSerializable() 注解告诉生成器需要为这个类生成序列化代码
  3. _$TokenFromJson 和 _$UserToJson 是自动生成的函数,前缀 _$ 是生成器的命名约定
  4. 模型类应尽可能使用不可变字段(final),这符合函数式编程的最佳实践

2. 生成序列化代码 爱壹帆电影 xxxxx 爱壹帆国际版

配置好模型类后,我们需要运行代码生成器。在项目根目录执行: xnxx 小寶影院 小宝影院在线视频 aiyifan 小宝影院电影 爱壹帆在线 小宝影院 小姐

flutter pub run build_runner build

这个命令会: 电影aiyifan

  1. 扫描项目中所有被 @JsonSerializable() 注解的类
  2. 为每个类生成对应的 .g.dart 文件
  3. 生成的代码包含完整的序列化和反序列化实现

对于大型项目,推荐使用watch模式,它会监听文件变化并自动重新生成代码: 爱一帆电影

flutter pub run build_runner watch

高级配置与技巧

  1. 字段自定义配置

json_serializable 提供了丰富的配置选项,通过 @JsonKey 注解可以精细控制每个字段的序列化行为: 免费在线影院 小寶影院电影

@JsonSerializable()
class AdvancedUser {
  @JsonKey(name: 'user_name') // 自定义JSON字段名
  final String name;
  
  @JsonKey(ignore: true) // 忽略此字段,不参与序列化
  final String? temporaryToken;
  
  @JsonKey(defaultValue: 'unknown') // 默认值
  final String status;
  
  @JsonKey(fromJson: _parseBalance, toJson: _stringifyBalance) // 自定义转换
  final double balance;
  
  @JsonKey(includeIfNull: false) // 为null时不包含在JSON中
  final String? nickname;
  
  AdvancedUser({
    required this.name,
    this.temporaryToken,
    this.status = 'unknown',
    required this.balance,
    this.nickname,
  });
  
  static double _parseBalance(String json) => double.parse(json);
  static String _stringifyBalance(double balance) => balance.toStringAsFixed(2);
  
  // ... fromJson/toJson方法
}
  1. 处理复杂嵌套结构

现实项目中的数据往往具有复杂的嵌套结构,json_serializable 可以优雅地处理这种情况: 爱一帆 爱一帆电影 爱一帆电影 外围

@JsonSerializable()
class Address {
  final String street;
  final String city;
  final String zipCode;
  
  Address({required this.street, required this.city, required this.zipCode});
  
  factory Address.fromJson(Map<String, dynamic> json) => _$AddressFromJson(json);
  Map<String, dynamic> toJson() => _$AddressToJson(this);
}
 
@JsonSerializable()
class Company {
  final String name;
  final Address address;
  
  Company({required this.name, required this.address});
  
  factory Company.fromJson(Map<String, dynamic> json) => _$CompanyFromJson(json);
  Map<String, dynamic> toJson() => _$CompanyToJson(this);
}
 
@JsonSerializable()
class Employee {
  final String id;
  final String name;
  final Company company;
  final List<String> skills; // 简单列表
  final List<Address> previousAddresses; // 复杂对象列表
  
  Employee({
    required this.id,
    required this.name,
    required this.company,
    required this.skills,
    required this.previousAddresses,
  });
  
  factory Employee.fromJson(Map<String, dynamic> json) => _$EmployeeFromJson(json);
  Map<String, dynamic> toJson() => _$EmployeeToJson(this);
}
  1. 枚举和泛型支持

json_serializable 对枚举和泛型也有很好的支持: 爱壹帆免费版 xxxvideo iyf 小宝影院

enum UserRole {
  @JsonValue('admin')
  admin,
  @JsonValue('editor')
  editor,
  @JsonValue('viewer')
  viewer,
  @JsonValue('guest')
  guest,
}
 
@JsonSerializable(genericArgumentFactories: true) // 启用泛型支持
class PaginatedResponse<T> {
  final int page;
  final int totalPages;
  final List<T> data;
  
  PaginatedResponse({
    required this.page,
    required this.totalPages,
    required this.data,
  });
  
  factory PaginatedResponse.fromJson(
    Map<String, dynamic> json,
    T Function(Object? json) fromJsonT,
  ) => _$PaginatedResponseFromJson(json, fromJsonT);
  
  Map<String, dynamic> toJson(Object? Function(T value) toJsonT) =>
      _$PaginatedResponseToJson(this, toJsonT);
}
 
// 使用示例
final userResponse = PaginatedResponse<User>.fromJson(
  jsonMap,
  (json) => User.fromJson(json as Map<String, dynamic>),
);

性能优化

  1. 批量生成:一次性为所有模型生成代码,而不是频繁运行生成器
  2. 使用 freezed:结合 freezed 包可以生成不可变类,获得更好的性能和安全性
  3. 缓存结果:对于频繁访问的 JSON 数据,考虑在转换为对象后缓存结果
  4. 懒加载:对于大型 JSON 结构,考虑使用懒加载或分页技术

FQA

DateTime 类型的处理 电影小宝影院 华人影视 爱壹帆 爱壹帆影视 寻芳阁

@JsonKey(fromJson: _dateFromJson, toJson: _dateToJson)
final DateTime createdAt;
 
static DateTime _dateFromJson(String json) => DateTime.parse(json);
static String _dateToJson(DateTime date) => date.toIso8601String();

处理可能为 null 的字段 小姐

@JsonSerializable()
class Product {
  final String id;
  final String name;
  final String? description; // 可空字段
  
  Product({required this.id, required this.name, this.description});
  
  factory Product.fromJson(Map<String, dynamic> json) => _$ProductFromJson(json);
  Map<String, dynamic> toJson() => _$ProductToJson(this);
}

  伴游 会所

00目录 0
    讨论 我来说一句 发布发表评论 发布0等 0 人为本文章充电 还没有介绍自己 关注