Flutter dio结合json_serializable请求数据并解析Demo

前言

我们在开发中,会面临要从服务器请求数据,然后解析服务器过来的json数据,这个在android中,都有相应的的封装好的很好的插件可以做这样的事情,请求数据有okHttp,解析有GSON。那么在flutter中呢,对应的可以是什么呢,我目前请求数据使用的是dio,解析使用的是json_serializable,下面是一个简单的例子

实践

一、集成插件

pubspec.yaml文件中添加diojson_serializable的相关插件,这里我贴上我的:

dependencies:
  flutter:
    sdk: flutter

  dio: ^1.0.0 #网络请求
  json_annotation: ^0.2.3

dev_dependencies:
  flutter_test:
    sdk: flutter

  #这两个是dev的,不要放到上面去了哦
  build_runner: ^0.9.0
  json_serializable: ^0.5.4

二、封装网络请求

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

//要查网络请求的日志可以使用过滤
class NetUtil {
  static const String GET = "get";
  static const String POST = "post";

  //get请求
  static void get(String url, Function callBack,
      {Map params, Function errorCallBack}) async {
    _request(Api.BaseUrl + url, callBack,
        method: GET, params: params, errorCallBack: errorCallBack);
  }

  //post请求
  static void post(String url, Function callBack,
      {Map params, Function errorCallBack}) async {
    _request(url, callBack,
        method: POST, params: params, errorCallBack: errorCallBack);
  }

  //具体的还是要看返回数据的基本结构
  //公共代码部分
  static void _request(String url, Function callBack,
      {String method,
      Map params,
      Function errorCallBack}) async {
    print(" url :<" + method + ">" + url);

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

    String errorMsg = "";
    int statusCode;

    try {
      Response response;
     if (method == GET) {
        //组合GET请求的参数
        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;

      //处理错误部分
      if (statusCode < 0) {
        errorMsg = "网络请求错误,状态码:" + statusCode.toString();
        _handError(errorCallBack, errorMsg);
        return;
      }

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

  //处理异常
  static void _handError(Function errorCallback, String errorMsg) {
    if (errorCallback != null) {
      errorCallback(errorMsg);
    }
    print(" errorMsg :" + errorMsg);
  }
}

以上的封装,主要基于返回的数据结构,我造了个数据,大概长下面这样:

在这里,我使用mocky来创建API

{
  "statusCode": 1,
  "data": {
    "name": "zoe",
    "email": "[email protected]",
    "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"
    ]
  }
}
Flutter dio结合json_serializable请求数据并解析Demo_第1张图片
image

三、创建model

为了便利的使用json_serializable库,我们使用这位大牛的这个小工具:

Flutter dio结合json_serializable请求数据并解析Demo_第2张图片
image

将右侧框内转换过的内容复制下来,在自己项目中创建user.dart文件,将你复制的内容粘贴进去。然后你会看到类中一些地方会飘红线,这是正常的哈:

Flutter dio结合json_serializable请求数据并解析Demo_第3张图片
image

这个时候,你在项目根目录下输入命令:flutter packages pub run build_runner build,完成之后会在user.dart同级目录下,自动创建一个名为user.g.dart的文件:

Flutter dio结合json_serializable请求数据并解析Demo_第4张图片
image

以下是日志(其中会有一些警告信息,比如Unable to resolve asset ID for "dart:ui",在我看来,好像不影响哈,暂时可以不用管):

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 {
  String name = "";
  String email = "";
  List picList = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("JSON"),
      ),
      body: (picList != null && picList.length == 0)
          ? LoadingComponent()
          : SingleChildScrollView(
              child: Column(
                children: [
                  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();
  }

  //获取网络数据
  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

写在最后

本人刚入门,所学尚浅,如有不当或不足之处,希望能得到指点

你可能感兴趣的:(Flutter dio结合json_serializable请求数据并解析Demo)