JSON 序列化
Flutter 应用在与后端 API 交互时,需要将 JSON 字符串解析为 Dart 对象,以及将 Dart 对象序列化为 JSON 字符串。
手动解析
适合小型项目或数据结构简单的场景。
jsonDecode
dart
import 'dart:convert';
final jsonString = '{"name": "张三", "age": 25, "email": "zhang@example.com"}';
// 解析为 Map
final Map<String, dynamic> json = jsonDecode(jsonString);
print(json['name']); // 张三
// 解析为 List
final jsonArray = '[1, 2, 3]';
final List<dynamic> list = jsonDecode(jsonArray);手动创建 Model 类
dart
class User {
final String name;
final int age;
final String email;
User({required this.name, required this.age, required this.email});
// 从 JSON Map 创建对象
factory User.fromJson(Map<String, dynamic> json) {
return User(
name: json['name'] as String,
age: json['age'] as int,
email: json['email'] as String,
);
}
// 转换为 JSON Map
Map<String, dynamic> toJson() {
return {
'name': name,
'age': age,
'email': email,
};
}
}使用:
dart
// JSON → 对象
final jsonString = '{"name": "张三", "age": 25, "email": "zhang@example.com"}';
final json = jsonDecode(jsonString) as Map<String, dynamic>;
final user = User.fromJson(json);
// 对象 → JSON
final jsonMap = user.toJson();
final jsonString = jsonEncode(jsonMap);嵌套对象
dart
class Address {
final String city;
final String street;
Address({required this.city, required this.street});
factory Address.fromJson(Map<String, dynamic> json) {
return Address(
city: json['city'] as String,
street: json['street'] as String,
);
}
Map<String, dynamic> toJson() => {'city': city, 'street': street};
}
class User {
final String name;
final Address address; // 嵌套对象
User({required this.name, required this.address});
factory User.fromJson(Map<String, dynamic> json) {
return User(
name: json['name'] as String,
address: Address.fromJson(json['address'] as Map<String, dynamic>),
);
}
Map<String, dynamic> toJson() => {
'name': name,
'address': address.toJson(),
};
}代码生成(json_serializable)
手动编写 fromJson 和 toJson 代码量大且容易出错,json_serializable 可以自动生成这些代码。
安装
bash
flutter pub add json_annotation
flutter pub add dev:json_serializable
flutter pub add dev:build_runner编写 Model
dart
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
@JsonSerializable()
class User {
final String name;
final int age;
final String email;
User({required this.name, required this.age, required this.email});
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}生成代码
bash
# 一次性生成
dart run build_runner build
# 监听变化,自动重新生成(开发时推荐)
dart run build_runner watch生成的 user.g.dart 文件包含 _$UserFromJson 和 _$UserToJson 方法。
常用注解
dart
@JsonKey(name: 'user_name') // JSON 中字段名与 Dart 属性名不同
final String userName;
@JsonKey(defaultValue: '') // 默认值
final String nickname;
@JsonKey(ignore: true) // 忽略该字段
final String internalId;
@JsonKey(fromJson: _fromJson) // 自定义解析
final DateTime createdAt;嵌套对象
dart
@JsonSerializable()
class Address {
final String city;
final String street;
Address({required this.city, required this.street});
factory Address.fromJson(Map<String, dynamic> json) => _$AddressFromJson(json);
Map<String, dynamic> toJson() => _$AddressToJson(this);
}
@JsonSerializable()
class User {
final String name;
final Address address;
User({required this.name, required this.address});
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}最佳实践
- 小型项目 / 快速原型:手动解析即可,减少依赖
- 正式项目:使用
json_serializable,减少手写错误 - API 响应统一处理:
dart
// 通用 API 响应结构
class ApiResponse<T> {
final int code;
final String message;
final T? data;
ApiResponse({required this.code, required this.message, this.data});
bool get isSuccess => code == 0;
}
// 使用
final response = await dio.get('/users/1');
final apiResponse = ApiResponse<Map<String, dynamic>>.fromJson(response.data);
if (apiResponse.isSuccess) {
final user = User.fromJson(apiResponse.data!);
}- 在 Isolate 中解析大 JSON:避免主线程卡顿
dart
import 'package:flutter/foundation.dart';
Future<Map<String, dynamic>> parseJsonInIsolate(String jsonString) async {
return compute((String str) => jsonDecode(str) as Map<String, dynamic>, jsonString);
}下一步
- 本地存储 — SharedPreferences / 文件读写
