Flutter dio結(jié)合json_serializable請(qǐng)求數(shù)據(jù)并解析Demo

前言

我們?cè)陂_(kāi)發(fā)中,會(huì)面臨要從服務(wù)器請(qǐng)求數(shù)據(jù)况凉,然后解析服務(wù)器過(guò)來(lái)的json數(shù)據(jù)进鸠,這個(gè)在android中,都有相應(yīng)的的封裝好的很好的插件可以做這樣的事情碱屁,請(qǐng)求數(shù)據(jù)有okHttp磷脯,解析有GSON。那么在flutter中呢娩脾,對(duì)應(yīng)的可以是什么呢赵誓,我目前請(qǐng)求數(shù)據(jù)使用的是dio,解析使用的是json_serializable柿赊,下面是一個(gè)簡(jiǎn)單的例子

實(shí)踐

一俩功、集成插件

pubspec.yaml文件中添加diojson_serializable的相關(guān)插件,這里我貼上我的:

dependencies:
  flutter:
    sdk: flutter

  dio: ^3.0.8 #網(wǎng)絡(luò)請(qǐng)求
  json_annotation: ^3.0.1

dev_dependencies:
  flutter_test:
    sdk: flutter

  #這兩個(gè)是dev的碰声,不要放到上面去了哦
  build_runner: ^1.7.3
  json_serializable: ^3.2.5

二诡蜓、封裝網(wǎng)絡(luò)請(qǐng)求

import 'package:dio/dio.dart';
import 'dart:convert';
import 'package:the_first_one/model/Api.dart';

//要查網(wǎng)絡(luò)請(qǐng)求的日志可以使用過(guò)濾<net>
class NetUtil {
  static const String GET = "get";
  static const String POST = "post";

  //get請(qǐng)求
  static void get(String url, Function callBack,
      {Map<String, String> params, Function errorCallBack}) async {
    _request(Api.BaseUrl + url, callBack,
        method: GET, params: params, errorCallBack: errorCallBack);
  }

  //post請(qǐng)求
  static void post(String url, Function callBack,
      {Map<String, String> params, Function errorCallBack}) async {
    _request(url, callBack,
        method: POST, params: params, errorCallBack: errorCallBack);
  }

  //具體的還是要看返回?cái)?shù)據(jù)的基本結(jié)構(gòu)
  //公共代碼部分
  static void _request(String url, Function callBack,
      {String method,
      Map<String, String> params,
      Function errorCallBack}) async {
    print("<net> url :<" + method + ">" + url);

    if (params != null && params.isNotEmpty) {
      print("<net> params :" + params.toString());
    }

    String errorMsg = "";
    int statusCode;

    try {
      Response response;
     if (method == GET) {
        //組合GET請(qǐng)求的參數(shù)
        if (params != null && params.isNotEmpty) {
          StringBuffer sb = new StringBuffer("?");
          params.forEach((key, value) {
            sb.write("$key" + "=" + "$value" + "&");
          });
          String paramStr = sb.toString();
          paramStr = paramStr.substring(0, paramStr.length - 1);
          url += paramStr;
        }
        response = await Dio().get(url);
      } else {
        if (params != null && params.isNotEmpty) {
          response = await Dio().post(url, data: params);
        } else {
          response = await Dio().post(url);
        }
      }

      statusCode = response.statusCode;

      //處理錯(cuò)誤部分
      if (statusCode < 0) {
        errorMsg = "網(wǎng)絡(luò)請(qǐng)求錯(cuò)誤,狀態(tài)碼:" + statusCode.toString();
        _handError(errorCallBack, errorMsg);
        return;
      }

      if (callBack != null) {
        callBack(response.data["data"]);
        print("<net> response data:" + response.data["data"]);
      }
    } catch (exception) {
      _handError(errorCallBack, exception.toString());
    }
  }

  //處理異常
  static void _handError(Function errorCallback, String errorMsg) {
    if (errorCallback != null) {
      errorCallback(errorMsg);
    }
    print("<net> errorMsg :" + errorMsg);
  }
}

以上的封裝,主要基于返回的數(shù)據(jù)結(jié)構(gòu)奥邮,我造了個(gè)數(shù)據(jù)万牺,大概長(zhǎng)下面這樣:

在這里罗珍,我使用mocky來(lái)創(chuàng)建API

{
  "statusCode": 1,
  "data": {
    "name": "zoe",
    "email": "zoey@qq.com",
    "pics": [
      "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1534747043&di=2e3d49c934bb603bcf3f2fe8befd94fc&imgtype=jpg&er=1&src=http%3A%2F%2Fimg0.pconline.com.cn%2Fpconline%2F1309%2F30%2F3571757_9.jpg",
      "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1534152325030&di=d1d8493bfe1d5f7a9715b6db8ef3d29d&imgtype=0&src=http%3A%2F%2Fc1.cdn.goumin.com%2Fcms%2Fdetail%2Fday_171101%2F20171101_140dd79.png",
      "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1534152325029&di=684aa3a8225a7828ba6b04c8ea4bccd3&imgtype=0&src=http%3A%2F%2Fimgq.duitang.com%2Fuploads%2Fblog%2F201505%2F15%2F20150515014759_Qz5Tw.thumb.700_0.jpeg"
    ]
  }
}
image

三、創(chuàng)建model

為了便利的使用json_serializable庫(kù)脚粟,我們使用這位大牛這個(gè)小工具

image

將右側(cè)框內(nèi)轉(zhuǎn)換過(guò)的內(nèi)容復(fù)制下來(lái)覆旱,在自己項(xiàng)目中創(chuàng)建user.dart文件,將你復(fù)制的內(nèi)容粘貼進(jìn)去核无。然后你會(huì)看到類(lèi)中一些地方會(huì)飄紅線扣唱,這是正常的哈,執(zhí)行下面的命令后就會(huì)好了:

image

這個(gè)時(shí)候团南,你在項(xiàng)目根目錄下輸入命令:flutter packages pub run build_runner build(這個(gè)命令需要每次在model類(lèi)中進(jìn)行更改時(shí)都要手動(dòng)運(yùn)行構(gòu)建噪沙。也可以使用命令:flutter packages pub run build_runner watch,它會(huì)監(jiān)視我們項(xiàng)目中文件的變化,并在需要時(shí)自動(dòng)構(gòu)建必要的文件,只需啟動(dòng)一次觀察器吐根,然后并讓它在后臺(tái)運(yùn)行正歼,這是安全的。個(gè)人推薦后面這個(gè)命令哈)拷橘,完成之后會(huì)在user.dart同級(jí)目錄下局义,自動(dòng)創(chuàng)建一個(gè)名為user.g.dart的文件:

image

有時(shí)候也會(huì)有些很詭異的事情出現(xiàn),比如不管怎么輸命令冗疮,最后就是生成不了g.dart文件萄唇,這時(shí)候可以使用命令flutter packages pub run build_runner build --delete-conflicting-outputs,將所有的都刪除术幔,重新生成另萤,一般都會(huì)變好,我也是不曉得為什么

以下是日志(其中會(huì)有一些警告信息诅挑,比如Unable to resolve asset ID for "dart:ui"四敞,在我看來(lái),好像不影響哈拔妥,暫時(shí)可以不用管):

F:\FlutterSpace\flutter_the_first_demo>flutter packages pub run build_runner build
[INFO] Generating build script...
[INFO] Generating build script completed, took 465ms

[INFO] Initializing inputs
[INFO] Reading cached asset graph...
[WARNING] Throwing away cached asset graph due to version mismatch.
[INFO] Reading cached asset graph completed, took 57ms

[INFO] Building new asset graph...
[INFO] Building new asset graph completed, took 522ms

[INFO] Checking for unexpected pre-existing outputs....
[INFO] Checking for unexpected pre-existing outputs. completed, took 2ms

[INFO] Running build...
[INFO] 2.6s elapsed, 3/65 actions completed.
[INFO] 3.6s elapsed, 4/65 actions completed.
[INFO] 4.7s elapsed, 4/65 actions completed.
[INFO] 5.7s elapsed, 4/65 actions completed.
[INFO] 6.8s elapsed, 4/65 actions completed.
[INFO] 7.9s elapsed, 4/65 actions completed.
[INFO] 9.0s elapsed, 4/65 actions completed.
[INFO] 10.0s elapsed, 4/65 actions completed.
[SEVERE] json_serializable on lib/components/BottomComponent2.dart:
Unable to resolve asset ID for "dart:ui"
[INFO] 17.0s elapsed, 56/65 actions completed.
[INFO] Running build completed, took 17.7s

[INFO] Caching finalized dependency graph...
[INFO] Caching finalized dependency graph completed, took 52ms

[SEVERE] Failed after 17.8s
pub finished with exit code 1

使用

import 'package:flutter/material.dart';
import 'package:the_first_one/model/user.dart';
import 'package:the_first_one/utils/NetUtil.dart';
import 'package:the_first_one/components/LoadingComponent.dart';

class JsonSeralizablePage extends StatefulWidget {
  @override
  _JsonSeralizablePageState createState() => _JsonSeralizablePageState();
}

class _JsonSeralizablePageState extends State<JsonSeralizablePage> {
  String name = "";
  String email = "";
  List<String> picList = <String>[];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("JSON"),
      ),
      body: (picList != null && picList.length == 0)
          ? LoadingComponent()
          : SingleChildScrollView(
              child: Column(
                children: <Widget>[
                  Text(
                    name,
                    style: TextStyle(color: Colors.black, fontSize: 20.0),
                  ),
                  SizedBox(height: 20.0),
                  Text(
                    email,
                    style: TextStyle(color: Colors.black, fontSize: 15.0),
                  ),
                  SizedBox(height: 20.0),
                  SizedBox(
                    height: 250.0 * picList.length,
                    child: ListView.builder(
                      physics: ClampingScrollPhysics(),
                      itemCount: picList != null && picList.length > 0
                          ? picList.length
                          : 0,
                      itemBuilder: (BuildContext context, int index) {
                        return picList != null && picList.length > 0
                            ? Image(
                                image: NetworkImage(picList[index]),
                                width: 400.0,
                                height: 250.0,
                                fit: BoxFit.cover)
                            : Text("no pics");
                      },
                    ),
                  ),
                ],
              ),
            ),
    );
  }

  @override
  void initState() {
    super.initState();

    getContent();
  }

  //獲取網(wǎng)絡(luò)數(shù)據(jù)
  void getContent() {
    NetUtil.get("http://www.mocky.io/v2/5b7143ae3200001402f36c46", (data) {
      User user = User.fromJson(data);
      setState(() {
        name = user.name;
        email = user.email;
        picList = user.pics;
      });
    }, errorCallBack: (errorMsg) {
      print("error:" + errorMsg);
    });
  }
}

效果:

image

寫(xiě)在最后

本人剛?cè)腴T(mén)目养,所學(xué)尚淺,如有不當(dāng)或不足之處毒嫡,希望能得到指點(diǎn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末癌蚁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子兜畸,更是在濱河造成了極大的恐慌努释,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咬摇,死亡現(xiàn)場(chǎng)離奇詭異伐蒂,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)肛鹏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)逸邦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)恩沛,“玉大人,你說(shuō)我怎么就攤上這事缕减±卓停” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵桥狡,是天一觀的道長(zhǎng)搅裙。 經(jīng)常有香客問(wèn)我,道長(zhǎng)裹芝,這世上最難降的妖魔是什么部逮? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮嫂易,結(jié)果婚禮上兄朋,老公的妹妹穿的比我還像新娘。我一直安慰自己怜械,他們只是感情好蜈漓,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著宫盔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪享完。 梳的紋絲不亂的頭發(fā)上灼芭,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音般又,去河邊找鬼彼绷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛茴迁,可吹牛的內(nèi)容都是我干的寄悯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼堕义,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼猜旬!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起倦卖,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤洒擦,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后怕膛,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體熟嫩,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年褐捻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掸茅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片椅邓。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖昧狮,靈堂內(nèi)的尸體忽然破棺而出景馁,到底是詐尸還是另有隱情,我是刑警寧澤陵且,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布裁僧,位于F島的核電站,受9級(jí)特大地震影響慕购,放射性物質(zhì)發(fā)生泄漏聊疲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一沪悲、第九天 我趴在偏房一處隱蔽的房頂上張望获洲。 院中可真熱鬧,春花似錦殿如、人聲如沸贡珊。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)门岔。三九已至,卻和暖如春烤送,著一層夾襖步出監(jiān)牢的瞬間寒随,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工帮坚, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留妻往,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓试和,卻偏偏與公主長(zhǎng)得像讯泣,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子阅悍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容