美文网首页FlutterFlutter中文社区Flutter圈子
Flutter dio结合json_serializable请求

Flutter dio结合json_serializable请求

作者: 周南城 | 来源:发表于2018-08-14 10:46 被阅读47次

    前言

    我们在开发中,会面临要从服务器请求数据,然后解析服务器过来的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';
    
    //要查网络请求的日志可以使用过滤<net>
    class NetUtil {
      static const String GET = "get";
      static const String POST = "post";
    
      //get请求
      static void get(String url, Function callBack,
          {Map<String, String> params, Function errorCallBack}) async {
        if (!url.startsWith("http")) {
          url = Api.BaseUrl + url;
        }
    
        _request(url, callBack,
            method: GET, params: params, errorCallBack: errorCallBack);
      }
    
      //post请求
      static void post(String url, Function callBack,
          {Map<String, String> params, Function errorCallBack}) async {
        _request(url, callBack,
            method: POST, params: params, errorCallBack: errorCallBack);
      }
    
      //具体的还是要看返回数据的基本结构
      //公共代码部分
      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请求的参数
            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("<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);
      }
    }
    

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

    在这里,我使用mocky来创建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

    三、创建model

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

    image

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

    image

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

    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<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();
      }
    
      //获取网络数据
      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

    写在最后

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

    相关文章

      网友评论

      • 2f615bb82ab4:同问,你的源码哪里可以下?
        周南城:https://github.com/Urwateryi/flutter_the_first_demo/tree/master/lib/home/jsonserializable
      • e610c0871fa3:能贴源码吗
        周南城:https://github.com/Urwateryi/flutter_the_first_demo/tree/master/lib/home/jsonserializable

      本文标题:Flutter dio结合json_serializable请求

      本文链接:https://www.haomeiwen.com/subject/pbpmbftx.html