flutter json數據處理

本文涉及的業務場景

只要咱們的app不是單機的,那麼必然涉及到遠程服務器數據請求。在flutter中,發起請求已經有現成的包dio了,使用起來也很是簡練方便,如仍是不是很瞭解,能夠點擊查看dio的詳細文檔javascript

發起請求,拿到服務端返回的json數據後,接下來的步驟是怎麼樣的。flutter(應該說是Dart)可不像javascript那樣,對json天生友好。這就是本文要講的主要內容。你將會學到:html

  • flutter項目json數據處理的詳細步驟和踩坑提醒
  • json_serializable環節,命令行+工具,幫你自動化生成相關代碼,無需手敲,無需手敲(重要的事情說兩遍)
  • 數據和源碼都爲你準備穩當,無需手敲(即便小白,也能夠輕鬆上手)

json數據讀取和處理

請求回來數據後,下一步必然就是讀取其中的數據信息,而後依此進行界面展現和邏輯處理了。java

若是返回來的是簡單的數據,並且業務邏輯也很簡單,那麼其實處理方式也能夠簡單化,例如服務端返回數據以下:git

{
        code: 200,
        message: null,
        value: true
    }
複製代碼

那麼,你甚至能夠這麼處理:github

if (jsonStr.indexOf('true') != -1) {
        // do something
    }
複製代碼

總結的說,在這種場景下面,使用正則表達式匹配或者簡單字符串處理邏輯,進行簡單快速的實現,也不失爲一種好方法。正則表達式

json反序列化

可是,當數據結構足夠複雜(例如:點擊查看複雜數據示例),那麼上述的方式顯然就有點捉襟見肘了。shell

這個時候,就該輪到本文要講述的重點,json反序列化上場了。關於序列化和反序列化,能夠上網查一下,有不少資料(實在不想查,好吧,這裏有現成的,點擊序列化湊合着看一下吧...)。json

在本文描述的業務場景下面,也能夠簡單理解爲,咱們要作的,就是把經過dio拿到的服務端json字符串數據,轉換爲對象,而後就能夠愉快的訪問該對象中的字段值了。api

主要的步驟有兩個:bash

  • json字符串轉換爲Map對象
  • 使用json_serializable進行反序列化

具體步驟以下:

  • 添加依賴

參考下面代碼,往pubspec.yaml文件中添加json_annotationjson_serializablebuild_runner包。

dependencies:
  flutter:
    sdk: flutter
  
  json_annotation: ^3.0.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  
  json_serializable: ^3.2.0
  build_runner: ^1.6.5
複製代碼

添加完,記得flutter packages get

  • 使用在線代碼生成工具把json生成dart代碼,代碼命名爲xxxx.dart(文件一,會在下文的代碼中引用到)copy到項目中

若是你已經看過其餘相關文章,頗有多是要你根據json數據寫一個dart的實體類,其實,也能夠的,選擇你喜歡方式就好了。本文推薦工具生成,方便快捷,不易出錯,哈哈。。。

若是,你還沒來得及準備好試驗的json數據,點擊本文爲你提供的數據示例,copy到工具中,愉快的玩耍吧。

  • 在當前項目的目錄下運行flutter packages pub run build_runner build,命令執行完成,根據剛剛的xxxx.dart生成xxxx.g.dart(該文件生成後不要手動改,也無需引用,放着不動就是了)
  • 開始編碼
import 'dart:convert';
import 'package:xxxxxxx/xxxx.dart'; //引入上面說起的文件一

String jsonStr = '{"value":1}'; //你要進行反序列化的json字符串
Map<String ,dynamic> map = json.decode(jsonStr); //先轉成Map
           
MyObject obj = MyObject.fromJson(map); //假設class名爲MyObject,這個根據實際狀況調整
print(obj.value);
複製代碼

到此,基本就完成了數據的反序列化。上述代碼中,主要是兩個步驟:

  • String to Map
  • Map to MyObject

MyObject即引入的「文件一」中的類名,可根據實際狀況進行調整。

也可能你會有疑問,既然原生已經提供了String to Map,那麼只作到這一步,而後使用map對象進行接下來的coding,ok嗎。

其實,也是能夠的,只是。。。,下面舉個列子對比一下,便一目瞭然了。以該數據示例爲例,下面兩行代碼,訪問的字段是同樣的:

print(homePageList.value[0].modules[0].items[1].title);

print(map.entries.elementAt(2).value[0].entries.elementAt(5).value[0].entries.elementAt(11).value[1].entries.elementAt(0).value);
複製代碼

不知你喜歡哪一種方式呢。。。

複雜不規則數據處理

按照上述的具體步驟,基本能夠處理大部分的規則數據了,可是當你以數據示例爲數據源,一步一步操做coding完,訪問其中某些字段的值時,意想不到的事情發生了:

print(homePageList.value[0].modules[0].items[1].title); //正常打印

print(homePageList.value[0].modules[2].items[0].name); // 報錯
複製代碼

報錯信息:

The following NoSuchMethodError was throw building BlockRowFrame(dirty):
Class 'Modules' has no instance getter 'title'.
...
複製代碼

The following NoSuchMethodError was throw building BlockRowFrame(dirty)

這是由於,數據每一項的結構不一致致使的。數據示例中,字段name在前兩個modulesitems元素中並無,而在第三個modulesitems元素中,卻有了。

遇到這種狀況,只須要在用工具生成的"文件一"中對應的class,手動添加上對應的字段代碼,而後再從新運行一次flutter packages pub run build_runner build --delete-conflicting-outputs即可。

到此,關於flutter json數據處理分享就講完了。碼字不易,以爲此文對你有幫助的,麻煩點個贊鼓勵鼓勵。

後記

若是還有不清楚的地方。。。

不要緊,源碼伺候,點擊flutter_examples訪問對應的github項目,其中的「json格式請求結果反序列化與使用(dio & json_serializable demo)」實例,就是本文的代碼實現!

相關文章
相關標籤/搜索