Flutter 中 JSON 解析

本文介紹一下Flutter中如何進行json數據的解析。在移動端開發中,請求服務端返回json數據並解析是一個很常見的使用場景。Android原生開發中,有GsonFormat這樣的神器,一鍵生成JavaBean,並利用Gson實現json數據和對象的轉化;在React Native中更是得益於直接使用javascript語言,無需對json對象進行解析即可以直接訪問屬性。那麼在Flutter中如何實現對json數據的解析呢?
Flutter採用dart語言進行開發,dart具備不少核心庫,其中dart:convert庫中內置了json轉換器,能夠實現將json數據轉換成dart對象。簡單的使用以下:javascript

import 'dart:convert'; void main() { // 解析對象 String jsonStr1 = '{"name":"Curry","email":"SC@GSW.com"}'; Map<String, dynamic> map = json.decode(jsonStr1); print(map['name']); // 解析列表 String jsonStr2 = '[{"name":"Curry"},{"name":"Thompson"}]'; List list = json.decode(jsonStr2); // 輸出列表第一個對象的"name"屬性 print(list[0]["name"]); } 

解析json串的方法很簡單,直接調用json.decode()便可,可是因爲json.decode()方法返回類型爲dynamic,所以沒法進行類型的檢查,編譯時不會報錯,容易使程序發生錯誤。採起的作法是像原生開發同樣,新建一個model實體類,將json轉爲實體類對象。生成實體類的方法有如下兩種:css

方法一.手寫實體類

一個簡單的實體類實例以下html

class User{ final String name; final String email; User(this.name,this.email); // 命名構造函數 User.fromJson(Map<String, dynamic> json) : name = json['name'], email = json['email']; Map<String,dynamic> toJson() =>{ 'name':name, 'email':email }; } 

實體類中須要添加兩個方法:User.fromJson和toJson,其中,User.fromJson是一個命名構造函數,經過傳入的map構造出實體類對象;toJson()方法用於將實體類對象序列化爲json字符串。
使用方法以下:java

import 'dart:convert'; // 這裏須要替換爲實體類所在路徑 import 'package:json_parse_test/user.dart'; void main() { // 解析對象 String jsonStr1 = '{"name":"Curry","email":"SC@GSW.com"}'; Map<String, dynamic> map = json.decode(jsonStr1); User user = User.fromJson(map); print(user.name); // 解析列表 String jsonStr2 = '[{"name":"Curry"},{"name":"Thompson"}]'; List list= json.decode(jsonStr2); // 將列表中的第一個對象轉換成User對象 print(User.fromJson(list[0]).name); // 將對象序列化爲json串 // json.encode()會自動調用實體類中的toJson() String jsonText = json.encode(user); print(jsonText); } 

這樣就完成了將json轉化成實體對象,步驟很簡單,可是還有一個問題是,真的每一個實體類都要咱們本身去手寫嗎,有沒有相似GsonFormat這種一鍵生成實體類的插件呢。固然是有的,以前從鴻洋大神推薦的Flutter學習資源中偶然發現了一個神奇的網站:
https://javiercbk.github.io/json_to_dart/
git

 
JSON To Dart.png

 

能夠直接經過json生成實體類代碼,彷彿是發現了新大陸,不得不佩服開發出這些快捷工具的大神們,爲後面學習的人鋪平了道路。網站的操做很簡單,一看就會。github

方法二.經過json_serializable自動生成

json_serializable是Google官方推薦的一個json序列化庫。使用以前須要在pubspec.yaml文件中添加依賴項:
pubspec.yamljson

dependencies: # Your other regular dependencies here json_annotation: ^2.0.0 dev_dependencies: # Your other dev_dependencies here build_runner: ^1.0.0 json_serializable: ^2.0.0 

添加以後在項目根目錄文件夾中運行flutter packages get (或者在編輯器中點擊 「Packages Get」) 以在項目中使用這些新的依賴項。
使用時也是須要新建一個實體類網絡

import 'package:json_annotation/json_annotation.dart'; // user.g.dart經過命令自動生成 part 'user_model.g.dart'; @JsonSerializable() class User { // 自定義json字段名對應的屬性名,不是必須的 @JsonKey(name: 'userName') String name; String email; User(this.name, this.email); factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); Map<String, dynamic> toJson() => _$UserToJson(this); } 

須要咱們手寫的就這些,這時代碼會報錯,咱們須要運行命令來自動生成缺乏的文件,有兩種生成的方法:框架

  • 一次性生成
    在項目根目錄文件夾下運行
flutter packages pub run build_runner build
  • 持續生成
    在項目根目錄文件夾下運行
flutter packages pub run build_runner watch

二者的區別是,一次性生成只執行一次,後面每新建一個實體類都須要從新運行該命令;持續生成會在咱們編寫代碼的過程當中根據須要自動生成缺乏的文件。
以後解析json的方法和方法一相同編輯器

import 'dart:convert'; // 這裏須要替換爲實體類所在路徑 import 'package:json_parse_test/user.dart'; void main() { // 解析對象 String jsonStr = '{"name":"Curry","email":"SC@GSW.com"}'; Map<String, dynamic> map = json.decode(jsonStr); User user = User.fromJson(map); print(user.name); } 

這裏關於實體類的生成我找到了作人要簡單這位大神寫的網頁工具,一樣是能夠很方便地將json轉換成實體類代碼。

 
json_serializable實體類生成工具

生成代碼後點擊下載將實體類dart文件下載到本地,以後放到項目中,在項目根目錄運行上面提到的生成文件命令便可。
固然也能夠經過自已定義模板編寫腳原本生成實體類文件,具體作法能夠參考 《Flutter實戰》

 

總結

Flutter中json的解析分爲兩步:
1.經過json.decode()將json串轉換成dart對象(Map或List)
2.編寫實體類(兩種方法,手寫或自動生成),利用上一步獲得的dart對象構造出實體類對象
其實在實際的應用中,咱們從服務端返回的響應數據已經經過了網絡請求框架的封裝,好比很經常使用的Dio,咱們能夠直接從返回的響應中獲取到dart對象,省去了第一步,直接轉化成實體類對象便可。

連接:https://www.jianshu.com/p/830ecb047d3d

相關文章
相關標籤/搜索