这里写的是 Flutter 自带的 convert
的 json 转换。下面以 3 个实例来说明。
class Student {
String name;
int age;
Student({
required this.name,
required this.age,
});
/// 因为调用 jsonDecode 把 json 串转对象时,jsonDecode 方法的返回值是 map 类型,无法直接转成 Student 对象
factory Student.fromJson(Map<String, dynamic> parsedJson) {
return Student(
name: parsedJson['name'],
age: parsedJson['age'],
);
}
/// 这个方法在对象转json的时候自动被调用
Map toJson() {
Map map = Map();
map["name"] = this.name;
map["age"] = this.age;
return map;
}
}
String _getJsonStr() {
Student student = Student(name: "pig", age: 33);
String jsonStr = jsonEncode(student);
return jsonStr;
}
调用如下:
String data = _getJsonStr();
print("data = $data");
输出如下:
String jsonStr = _getJsonStr();
var data = jsonDecode(jsonStr);
print("data = $data, runtimeType = ${data.runtimeType}");
输出如下:
可以看出这个 data 类型是 map
类型,此时还没有转成 Student
对象。
要转成 Student 需要如下调用:
Student st = Student.fromJson(data);
print("st runtimeType = ${st.runtimeType}, st name = ${st.name}");
通过 Student.fromJson
的方法,把 map 转成 Student 对象,Student.fromJson
是定义在 Student 类中的,如下:
/// 因为调用 jsonDecode 把 json 串转对象时,jsonDecode 方法的返回值是 map 类型,无法直接转成 Student 对象
factory Student.fromJson(Map<String, dynamic> parsedJson) {
return Student(
name: parsedJson['name'],
age: parsedJson['age'],
);
}
方法很简单,就是把 map 中的数据取出来,构造成 Student 对象。
Student 类中嵌套 Grade 对象:
class Student {
String name;
int age;
Grade grade;
Student({required this.name,
required this.age,
required this.grade,
});
factory Student.fromJson(Map<String, dynamic> parsedJson) {
return Student(
name: parsedJson['name'],
age: parsedJson['age'],
grade: Grade.fromJson(parsedJson['grade']),
);
}
Map toJson() {
Map map = Map();
map["name"] = this.name;
map["age"] = this.age;
map["grade"] = this.grade;
return map;
}
}
class Grade {
String className;
String title;
Grade({required this.className, required this.title});
factory Grade.fromJson(Map<String, dynamic> parsedJson) {
return Grade(
className: parsedJson['className'],
title: parsedJson['title'],
);
}
Map toJson() {
Map map = Map();
map["className"] = this.className;
map["title"] = this.title;
return map;
}
}
没什么大的改变,主要就是 Student.fromJson
中获取 grade 的方式和获取普通变量的方式不一样,如下:
factory Student.fromJson(Map<String, dynamic> parsedJson) {
return Student(
name: parsedJson['name'],
age: parsedJson['age'],
grade: Grade.fromJson(parsedJson['grade']),
);
}
因为 parsedJson['grade']
得到的仍然是 map 类型,所以需要通过 Grade.fromJson
方法转成 Gradle 对象。
Student 中除了包含 Grade 对象外,还包含 Address 的列表。
各个类的定义如下:
class Student {
String name;
int age;
Grade grade;
List<Address> addressList;
Student(
{required this.name,
required this.age,
required this.grade,
required this.addressList});
factory Student.fromJson(Map<String, dynamic> parsedJson) {
/// addressList 是列表 和 grade 的处理方式不一样
/// 方式 1
List<Address> addressL = [];
var list = parsedJson['addressList'];
for (var address in list) {
addressL.add(Address.fromJson(address));
}
/// 方式 2,显然方式2的更加优雅
List<Address> addressL2 = (parsedJson['addressList'] as List<dynamic>)
.map((e) => Address.fromJson(e))
.toList();
return Student(
name: parsedJson['name'],
age: parsedJson['age'],
grade: Grade.fromJson(parsedJson['grade']),
addressList: addressL2,
);
}
Map toJson() {
Map map = Map();
map["name"] = this.name;
map["age"] = this.age;
map["grade"] = this.grade;
map['addressList'] = this.addressList;
return map;
}
}
class Grade {
String className;
String title;
Grade({required this.className, required this.title});
factory Grade.fromJson(Map<String, dynamic> parsedJson) {
return Grade(
className: parsedJson['className'],
title: parsedJson['title'],
);
}
Map toJson() {
Map map = Map();
map["className"] = this.className;
map["title"] = this.title;
return map;
}
}
class Address {
String street;
String district;
Address({required this.street, required this.district});
factory Address.fromJson(Map<String, dynamic> parsedJson) {
return Address(
street: parsedJson['street'],
district: parsedJson['district'],
);
}
Map toJson() {
Map map = Map();
map["street"] = this.street;
map["district"] = this.district;
return map;
}
}
主要的区别依然是 Student.fromJson
;
factory Student.fromJson(Map<String, dynamic> parsedJson) {
/// addressList 是列表 和 grade 的处理方式不一样
/// 方式 1
List<Address> addressL = [];
var list = parsedJson['addressList'];
for (var address in list) {
addressL.add(Address.fromJson(address));
}
/// 方式 2,显然方式2的更加优雅
List<Address> addressL2 = (parsedJson['addressList'] as List<dynamic>)
.map((e) => Address.fromJson(e))
.toList();
return Student(
name: parsedJson['name'],
age: parsedJson['age'],
grade: Grade.fromJson(parsedJson['grade']),
addressList: addressL2,
);
}
上面的 var list = parsedJson['addressList']
; 获取的类型是 List
,是无法直接转成 List< Address>,所以需要遍历 list ,然后通过 Address.fromJson(address)
把 list 里面的对象转成 Address 类型。
上面基本就说完了,其实你可以看看 json_serializable
这个插件,其实也是通过注解来实现上面类似的代码。