目的有兩個:
1、將json轉成dart類,發揮強類型的優勢,能夠.出來提示,不容出錯,默認情況下只能obj['name']方式來訪問屬性;
2、將dart類轉成json;入庫需要;
其實最原始的方法就是將獲取到的json字符串jsonDecode(jsonStr),這樣,如果jsonStr是對象,就能得到Map<String, dynamic>,如果jsonStr是數組,就能得到List<dynamic>,但是如果你需要獲取裏面的屬性,還是隻能使用obj['name']來問,這樣極容易出錯,所以才有了json 轉 dart 模型的需求。
例子一:json字符串是對象
print('格式化對象——————————————————只能通過obj["name"]方式使用');
String jsonString = '{"stationId":3,"stationName":"黃埔支行"}';
Map<String, dynamic> station = jsonDecode(jsonString);
print(station["stationName"]);
print(station.keys.map((k) => k).join(','));
print(station.values.map((k) => k).join(','));
print('');
例子二:json字符串是數組
print('格式化數組——————————————————');
String jsonStringList =
'[{"stationId":3,"stationName":"黃埔支行"}, {"stationId":4,"stationName":"黃埔支行444"}]';
final List<dynamic> station2 = jsonDecode(jsonStringList);
var stationList = station2.map((e) => e['stationName']).toList();
print(stationList);
print('');
我們可以使用這個工具JSON to Dart 將json字符串映射成對應的類:如上面的json字符串{"stationId":3,"stationName":"黃埔支行"}複製過去,就能轉換成如下類:
(自動生成的類名Autogenerated可以自行修改一下,假設改為Station)
//自動生成的類名Autogenerated改為Station
class Station {
int? stationId;
String? stationName;
Station({this.stationId, this.stationName});
Station.fromJson(Map<String, dynamic> json) {
stationId = json['stationId'];
stationName = json['stationName'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['stationId'] = this.stationId;
data['stationName'] = this.stationName;
return data;
}
}
例子三:json字符串對象轉成dart類對象
Map<String, dynamic> map = jsonDecode(jsonString);
Station stationModel = Station.fromJson(map);
print(
'json轉對象:stationModel.stationName=${stationModel.stationName} stationModel.stationName=${stationModel.stationName}',
);
print(
'對象轉json:${json.encode(stationModel)}',
); // 不需要調用 stationModel.toJson(),內部會自動完成
注意:首先還是需要對json字符串做jsonDecode()操作,然後就可以使用生成的方法Station.fromJson(map)就能得到Station對象了。
使用json.encode(stationModel)可以將類對象序列化為json字符串;並且不需要調用stationModel.toJson(),內部會自動完成。
例子四:json字符串數組轉成dart類對象數組
final List<dynamic> stationsJson = jsonDecode(jsonStringList);
List<Station> stationList2 = stationsJson
.map((e) => Station.fromJson(e))
.toList();
print(stationList2);
print(
'數組轉json:${json.encode(stationList2)}', //不需要調用 e.toJson(),內部會自動完成
);
其實和例子三差不多,首先還是jsonDecode,然後通過map,裏面還是調用Station.fromJson(),只是在map裏面循環調用例子三的操作。這樣就得到了dart類對象數組了。
同樣的,dart數組轉成json字符串,直接調用json.encode(),並且不需要調用 stationModel.toJson(),內部會自動完成。
當然,如果每次都需要賦值json去固定網站上轉dart類是比較繁瑣的,所以希望有其他方式來根據json自動生成這個dart類就好了。
官方提供的方式是:
1、自己定義一個模板,如下:
需要先安裝三個依賴插件:
flutter pub add dev:json_serializable
flutter pub add dev:build_runner
flutter pub add json_annotation
定義如下模板:
import 'package:json_annotation/json_annotation.dart';
// user.g.dart 將在我們運行生成命令後自動生成
part 'user.g.dart';
///這個標註是告訴生成器,這個類是需要生成Model類的
@JsonSerializable()
class User {
final String name;
final String email;
User(this.name, this.email);
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
這個時候會報錯,因為user.g.dart、UserFromJson等,目前還沒有生成;
然後執行命令,
flutter packages pub run build_runner build
// 或者:如果你手動修改模板,會自動重新生成user.g.dart文件
// flutter packages pub run build_runner watch
就會在user.dart類同一個文件夾下生成一個文件user.g.dart,這樣就做到了和上面一樣的效果了,但是不需要手動賦值json去網站上轉dart類。
2、根據json生成第一步需要的模板。
如果需要自己去定義模板,顯然很麻煩,還不如賦值json去網站上生成呢,所以我們需要根據json生成模板的需求,這裏提供一個插件,
Json to Dart Model
jsonToDart.fromSelectionToCodeGen