Flutter開發之JSON解析

xiangzhihong發表於2019-08-21

對於JSON格式的資料互動,想必大家不會陌生。JSON(全稱JavaScript Object Notation, JS 物件簡譜) 是一種輕量級的資料交換格式,JSON因為具有易於人閱讀和編寫,同時也易於機器解析和生成,並有效地提升網路傳輸效率等特性,通常被用在客戶端與服務端的資料互動中。

對於JSON的基本知識,本文不做詳細介紹,讀者可以自行搜尋資料進行學習。

手動解析

手動解析通常應用在一些基本簡單的場合,即資料結構不是很複雜的場景,手動解析JSON是指使用Flutter提供的dart:convert中內建的JSON解碼器。它能夠將原始JSON字串傳遞給json.decode() 方法,然後在返回的Map<String, dynamic>中查詢所需的值。 它不需要依賴任何第三方庫,對於小專案來說很方便。

例如,有下面一個介面:jsonplaceholder.typicode.com/posts/1,它的數…

{
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
複製程式碼

由於上面的資料格式比較簡單,因此我們可以使用手動解析的方式來解析它。

final responseJson = json.decode(response.body);
Map<String, dynamic> newTitle = responseJson ;
print(newTitle['title']);//列印title的值
複製程式碼

當然,我們也可以新建一個實體類,然後將它解析到實體類中。

final responseJson = json.decode(response.body);
print(responseJson.toString());
Post postBean = Post.fromJson(responseJson);    //Post為實體類
複製程式碼

對於資料結構不是很複雜的時候,使用fromJson來解析欄位還好,但是如果資料結構比較複雜的話,手寫fromJson、toJson就不太友好,並且容易出錯。

藉助工具解析

在Android原生開發中,我們可以使用諸如Gson、FastJson等第三方庫來幫助我們將JSON資料轉成實體類。同樣,在Flutter開發中,我們也可以使用外掛或工具來一鍵生成實體類。

例如,下面是豆瓣電影提供的獲取電影列表的一個介面,資料返回的格式如下:

{
count: 10,
start: 25,
total: 250,
subjects: [
{
rating: {
max: 10,
average: 9.1,
details: {

},
stars: "45",
min: 0
},
genres: [
"劇情",
"動作",
"科幻"
],
title: "蝙蝠俠:黑暗騎士",
casts: [
{
avatars: {
small: "http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1004.webp",
large: "http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1004.webp",
medium: "http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1004.webp"
},
name_en: "Christian Bale",
name: "克里斯蒂安·貝爾",
alt: "https://movie.douban.com/celebrity/1005773/",
id: "1005773"
},
{
avatars: {
small: "http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p13801.webp",
large: "http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p13801.webp",
medium: "http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p13801.webp"
},
name_en: "Heath Ledger",
name: "希斯·萊傑",
alt: "https://movie.douban.com/celebrity/1006957/",
id: "1006957"
},
{
avatars: {
small: "http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p522.webp",
large: "http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p522.webp",
medium: "http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p522.webp"
},
name_en: "Aaron Eckhart",
name: "艾倫·艾克哈特",
alt: "https://movie.douban.com/celebrity/1053577/",
id: "1053577"
}
],
durations: [
"152分鐘"
],
collect_count: 813292,
mainland_pubdate: "",
has_video: true,
original_title: "The Dark Knight",
subtype: "movie",
directors: [
{
avatars: {
small: "http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p673.webp",
large: "http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p673.webp",
medium: "http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p673.webp"
},
name_en: "Christopher Nolan",
name: "克里斯托弗·諾蘭",
alt: "https://movie.douban.com/celebrity/1054524/",
id: "1054524"
}
],
pubdates: [
"2008-07-14(紐約首映)",
"2008-07-18(美國)"
],
year: "2008",
images: {
small: "http://img1.doubanio.com/view/photo/s_ratio_poster/public/p462657443.webp",
large: "http://img1.doubanio.com/view/photo/s_ratio_poster/public/p462657443.webp",
medium: "http://img1.doubanio.com/view/photo/s_ratio_poster/public/p462657443.webp"
},
alt: "https://movie.douban.com/subject/1851857/",
id: "1851857"
},
title: "豆瓣電影Top250"
}
複製程式碼

如果我們使用fromJson、toJson來進行解析的話,就比較麻煩,並且還容易出錯,因此我們使用一些工具來輔助進行JSON解析。

線上生成

首先,開啟JSON to Dart,如下圖所示。

在這裡插入圖片描述
然後,我們將介面返回的JSON資料拷貝到輸入框中,點選建立Dart類,然後右邊就是生成好的Dart程式碼。
在這裡插入圖片描述
然後,建立一個Dart實體類,將上面生成的實體類程式碼拷貝過去即可。不過,我在使用此種方式進行JSON解析的時候,遇到一個問題,

Cannot generate dart code. Please check the project caveats.
複製程式碼

如下圖:

在這裡插入圖片描述
至於產生的原因我也不是非常清楚,有知道的可以解釋下。

FlutterJsonBeanFactory外掛

除了上面的方式外,我們還可以使用FlutterJsonBeanFactory外掛來輔助生成Bean類。 安裝FlutterJsonBeanFactory外掛很簡單,以Android Studio為例,依次選擇【Android Studio】->【Preferences…】->【Plugins】,然後搜尋FlutterJsonBeanFactory外掛安裝即可,如下圖所示。

在這裡插入圖片描述
安裝成功之後重啟Android Studio即可,重啟之後在new 的時候就會多一個【 dart bean class File from Json】選項,如下圖所示。
在這裡插入圖片描述
然後,在專案的lib目錄下右鍵並選擇【new】->【dart bean class File from JSON】來建立一個實體類,如下圖。
在這裡插入圖片描述
然後,點選【Make】按鈕就可以生成一個dart實體類,如下圖。
在這裡插入圖片描述
可以發現,使用JSON轉換外掛來輔助開發,對於Flutter開發是非常方便的。除了FlutterJsonBeanFactory外掛,另一款FlutterJsonHelper也可以完成JSON轉換為Entity實體類的任務。

需要說明的是,生成實體類時,類名後面的entity是自動加上去的,可以在設定中配置自定義名稱,如下圖。

在這裡插入圖片描述
然後,我們就可以使用dio庫或者httpclient來請求介面,並將它轉換到moviesentity實體類上,如下所示:

//獲取電影列表
void getFilmList() async {
    Dio dio = new Dio();
    Response response=await dio.get(hotMovies);
    print('電影資料:'+response.toString());

    Map userMap = json.decode(response.toString());
    var movies = new MoviesEntity.fromJson(userMap);
  }
複製程式碼

相關文章