一、内联反序列化
把JSON字符串转换成 Map<String, dynamic> 或者 List<dynamic>
import 'dart:convert';
main(List<String> args) {
JsonCodec json = new JsonCodec();
String str = '{"name":"tom"}';
Map<String, dynamic> a = json.decode(str);
print(a["name"]);
String str1 = '["a","b"]';
List<dynamic> b = json.decode(str1);
print(b.length);
String str3 = '{"name": "John Smith","email": "john@example.com"}';
var c = json.decode(str3);
print(c.runtimeType); //Map<String, dynamic>
String str4 = '{"name": "John Smith","email": ["a","b"]}';
var d = json.decode(str4);
print(d.runtimeType); //Map<String, dynamic>
String str5 = '{"name": "John Smith","email": {"a":"o","b":"p"}}';
var e = json.decode(str5);
print(e.runtimeType); //<String, dynamic>
// String str6 = '{"name": "John Smith","email": {"a","b"}}';
// var f = json.decode(str6); //FormatException: Unexpected character 报错
// print(e.runtimeType);
}
复杂些的比如
'{"age":19,"name":["tom","liu","wu"]}' ??
二、把字符串转成类对象
import 'dart:convert';
main(List<String> args) {
String str = '{"age":19,"name":"tom"}';
Map map = jsonDecode(str);
Student user = Student.ds(map);
print(user.age);
}
class Student {
int age;
String name;
//Student(this.age, this.name);
Student.ds(Map<String, dynamic> json)
: age = json['age'],
name = json['name'];
}
三、自动反序列化
使用 json_serializable https://pub.dev/packages/json_serializable
说明:用指令生成文件是在flutter中进行的,实际测试是在vscode中执行的。
不知道为什么flutter下使用flutter pub run build_runner build 正常,但是vscode中使用dart里的指令pub run build_runner build 生成不了文件。还有各式各样的版本问题,折腾了很久,感觉还不成熟
测试版本
Flutter 1.20.4 • channel stable
Dart SDK version: 2.9.2
导入包的版本
dependencies:
flutter:
sdk: flutter
json_annotation: ^3.0.0
dev_dependencies:
flutter_test:
sdk: flutter
build_runner: ^1.6.7
json_serializable: ^3.2.2
user.dart
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
@JsonSerializable()
class User {
User(this.name, this.email);
String name;
String email;
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
*.g.dart里 *要跟文件名相同
在flutter项目的根目录下,也就是有pubspec.yaml文件夹下,使用指令:flutter pub run build_runner build
如果想要自动序列化使用指令:flutter pub run build_runner watch
生成后的文件 user.g.dart
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'user.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
User _$UserFromJson(Map<String, dynamic> json) {
return User(
json['name'] as String,
json['email'] as String,
);
}
Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>{
'name': instance.name,
'email': instance.email,
};
使用
import 'dart:convert';
import './user.dart';
main(List<String> args) {
String jsonString = '{"name": "John", "email": "abc@163.com"}';
//序列化成map
Map<String, dynamic> map = jsonDecode(jsonString);
//转成对象
User user = User.fromJson(map);
print(user.email);
//json
print(user.toJson());
}
反序列化嵌套json
结构
user.dart
import 'address.dart';
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
@JsonSerializable()
class User {
String firstName;
Address address;
User(this.firstName, this.address);
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
address.dart
import 'package:json_annotation/json_annotation.dart';
part 'address.g.dart';
@JsonSerializable()
class Address {
String street;
String city;
Address(this.street, this.city);
factory Address.fromJson(Map<String, dynamic> json) => _$AddressFromJson(json);
Map<String, dynamic> toJson() => _$AddressToJson(this);
}
生成后的代码
user.g.dart
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'user.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
User _$UserFromJson(Map<String, dynamic> json) {
return User(
json['firstName'] as String,
json['address'] == null
? null
: Address.fromJson(json['address'] as Map<String, dynamic>),
);
}
Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>{
'firstName': instance.firstName,
'address': instance.address,
};
这里有个问题,不知道为什么生成的这个user.g.dart文件在as中不报错,但是在vscode中报错
稍微改了一下,改成
return User(
json['firstName'] as String,
json['address'] = Address.fromJson(json['address'] as Map<String, dynamic>),
);
address.g.dart
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'address.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Address _$AddressFromJson(Map<String, dynamic> json) {
return Address(
json['street'] as String,
json['city'] as String,
);
}
Map<String, dynamic> _$AddressToJson(Address instance) => <String, dynamic>{
'street': instance.street,
'city': instance.city,
};
测试运行
import 'dart:convert';
import './user.dart';
main(List<String> args) {
String jsonString = '{"firstName": "John", "address": {"street":"女贞路45号","city":"霍格沃茨"}}';
//序列化成map
Map<String, dynamic> map = jsonDecode(jsonString);
//转成对象
User user = User.fromJson(map);
print(user.firstName);
//
print(user.address.city);
//json
print(user.toJson());
}
对象都成功输出了
但是嵌套类转JSON的这个结果不是想要的.
修改user.dart
//括号里添加
@JsonSerializable(explicitToJson: true)
class User {
String firstName;
Address address;
修改user.g.dart
User _$UserFromJson(Map<String, dynamic> json) {
return User(
json['firstName'] as String,
//上面已经修改过
json['address'] = Address.fromJson(json['address'] as Map<String, dynamic>),
);
}
这个转json问题flutter里能成功,在vscode里纯dart方式失败?
修改user.g.dart 不是个好方法,使用指令时肯定有重新变回去了。