dio+json_serializable从请求到网络解析

栏目: IOS · Android · 发布时间: 5年前

内容简介:网络请求到数据解析是一个app必不可少的流程之一,在flutter官网中目前主要是介绍 自带的Http请求+Json解析 但是也推荐了更好的网路请求到组合的方式 dio 和 json_serializable,本篇文章主要介绍这两个方式的使用,源码在结尾本文同步更新于我的gitpagepackage地址

网络请求到数据解析是一个app必不可少的流程之一,在flutter官网中目前主要是介绍 自带的Http请求+Json解析 但是也推荐了更好的网路请求到组合的方式 dio 和 json_serializable,本篇文章主要介绍这两个方式的使用,源码在结尾

本文同步更新于我的gitpage xsfelvis.github.io/2018/12/08/…

dio

简介

package地址 pub.flutter-io.cn/packages/di… , 添加依赖

dependencies: dio: ^1.0.9 支持了 支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时等 Performing a  GET request: 简单的使用如下

Response response;
response=await dio.get("/test?id=12&name=wendu")
print(response.data.toString());
// Optionally the request above could also be done as
response=await dio.get("/test",data:{"id":12,"name":"wendu"})
print(response.data.toString());
复制代码

Performing a POST request:

response=await dio.post("/test",data:{"id":12,"name":"wendu"})
复制代码

Performing multiple concurrent requests:

response= await Future.wait([dio.post("/info"),dio.get("/token")]);
复制代码

Downloading a file:

response=await dio.download("https://www.google.cn/","./xx.html")
复制代码

Sending FormData:

FormData formData = new FormData.from({
   "name": "wendux",
   "age": 25,
});
response = await dio.post("/info", data: formData)
复制代码

Uploading multiple files to server by FormData:

FormData formData = new FormData.from({
   "name": "wendux",
   "age": 25,
   "file1": new UploadFileInfo(new File("./upload.txt"), "upload1.txt"),
   // upload with bytes (List<int>) 
   "file2": new UploadFileInfo.fromBytes(utf8.encode("hello world"),"word.txt"),
   // Pass multiple files within an Array 
   "files": [
      new UploadFileInfo(new File("./example/upload.txt"), "upload.txt"),
      new UploadFileInfo(new File("./example/upload.txt"), "upload.txt")
    ]
});
response = await dio.post("/info", data: formData)
复制代码

更多可以参考作者的说明文章以及 example

并且由于原生的Http不支持charles抓包,这个库可以使用设置代理来达到抓包的目的,ip自己替换

dio.onHttpClientCreate = (HttpClient client) {
  client.findProxy = (uri) {
    //proxy all request to localhost:8888
    return "PROXY yourIP:yourPort";
  };
};
复制代码

这样就可抓包了。

网络请求封装使用

简单封装使我们更加容易的使用,核心代码如下

void _request(String url, Function callBack,
      {String method,
      Map<String, String> params,
      Function errorCallBack}) async {
//    dio.onHttpClientCreate = (HttpClient client) {
//      client.findProxy = (uri) {
//        //proxy all request to localhost:8888
//        return "PROXY 172.23.235.153:8888";
//      };
//    };
    String errorMsg = "";
    int statusCode;
    try {
      Response response;
      if (method == 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 (method == POST) {
        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) {
        String res2Json  = json.encode(response.data);
        Map<String,dynamic> map=json.decode(res2Json);
        callBack(map["data"]);
      }
    } catch (exception) {
      _handError(errorCallBack, exception.toString());
    }
  }
复制代码

详细的可以参考源码 github.com/xsfelvis/le…

使用如下

HttpCore.instance.get(Api.HOME_BANNER, (data) {
  List<BannerData> banners = getBannersList(data);
  setState(() {
    slideData = banners;
  });
}, errorCallBack: (errorMsg) {
  print("error:" + errorMsg);
  return null;
});
复制代码

在封装网络库的的时候发现 底层 response.data['data']时候当是一个 jsonarray 时候竟然无法直接取出'data',"Stirng not subType of Index "错误,原因是 此时拿到的不是一个json数据,没有双引号的假json数据,但是在jsonobject却可以,解决如下

if (callBack != null) {
  String res2Json  = json.encode(response.data);
  Map<String,dynamic> map=json.decode(res2Json);
  callBack(map["data"]);
}
复制代码

json_serializable

简介

package地址 pub.flutter-io.cn/packages/js… 添加依赖

dependencies: json_serializable: ^2.0.0 dev_dependencies    build_runner: ^1.1.2    json_serializable: ^2.0.0

这个是个好东西,之前的相当于json数据一个个通过key解出来(关于自带的json解析可以参考 juejin.im/post/5b5d78… ),不仅耗时而且容易出错,json_serializable 让我们直接反序列化成对象直接使用类似于Gson,而且还提供了一个 工具 来自动帮助我们生成代码,简单快捷而且不容易出错

使用

以json

{
    "data":{
        "curPage":2,
        "datas":[
            {
                "apkLink":"",
                "author":"鸿洋",
                "chapterId":410,
                "chapterName":"玉刚说",
                "collect":false,
                "courseId":13,
                "desc":"",
                "envelopePic":"",
                "fresh":false,
                "id":7604,
                "link":"https://mp.weixin.qq.com/s/cCZKmqKrdCn63eWTbOuANw",
                "niceDate":"2018-12-03",
                "origin":"",
                "projectLink":"",
                "publishTime":1543830090000,
                "superChapterId":408,
                "superChapterName":"公众号",
                "tags":[
                    {
                        "name":"公众号",
                        "url":"/wxarticle/list/410/1"
                    }
                ],
                "title":"在 Retrofit 和 OkHttp 中使用网络缓存,提高访问效率",
                "type":0,
                "userId":-1,
                "visible":1,
                "zan":0
            },
            {
                "apkLink":"",
                "author":"鸿洋",
                "chapterId":408,
                "chapterName":"鸿洋",
                "collect":false,
                "courseId":13,
                "desc":"",
                "envelopePic":"",
                "fresh":false,
                "id":7605,
                "link":"https://mp.weixin.qq.com/s/r3AWeYafyMEc1-g8BWEHBg",
                "niceDate":"2018-12-03",
                "origin":"",
                "projectLink":"",
                "publishTime":1543766400000,
                "superChapterId":408,
                "superChapterName":"公众号",
                "tags":[
                    {
                        "name":"公众号",
                        "url":"/wxarticle/list/408/1"
                    }
                ],
                "title":"非 UI 线程能调用 View.invalidate()?",
                "type":0,
                "userId":-1,
                "visible":1,
                "zan":0
            }
        ],
        "offset":20,
        "over":false,
        "pageCount":289,
        "size":20,
        "total":5779
    },
    "errorCode":0,
    "errorMsg":""
}
复制代码

为例,我们首先找到实际数据信息,因为异errorcode 之类的处理已在上面的封装网络请求中处理了,这里需要关注 实际内容传递者 “data”里面的数据,将上面这个data里面的jsonObject,从data 这个key后面包括大括号一起复制到上面的代码生成工具网页里面,截图如下

dio+json_serializable从请求到网络解析

然后 当前项目的目录下运行 flutter packages pub run build_runner build

然就可以得到news.g.dart文件

然后在使用中通过获取对象属性的方式就可以直接拿到我们关注的字段了

//  获取News数据
void _getNewsList(int curpage) {
  var url = Api.HOME_ARTICLE + curpage.toString() + "/json";
  HttpCore.instance.get(url, (data) {
    News news = News.fromJson(data);
    List<Datas> newsDatas = news.datas;
    setState(() {
      listData = newsDatas;
    });
  });
}
复制代码

其他

自定义字段的处理

我们可以通过JsonKey自定义参数进行注释并自定义参数来自定义各个字段。例如:是否允许字段为空等。 注意,这里不加任何JsonKey默认允许空json字段。 比如解析字段有个横线, 而dart中只允许字母数字下划线作为变量名。所以我们必须对它进行特殊处理。@JsonKey(name="Nicehash-CNHeavy")来解析map,通常自动生成代码的工具已经可以帮助我们解决了

@JsonKey(name: 'off-set')
int offset;
复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C++设计新思维

C++设计新思维

(美)Andrei Alexandrescu / 侯捷、於春景 / 华中科技大学出版社 / 2003-03 / 59.8

本书从根本上展示了generic patterns(泛型模式)或pattern templates(模式模板),并将它们视之为“在C++中创造可扩充设计”的一种功能强大的新方法。这种方法结合了template和patterns,你可能未曾想过,但的确存在。为C++打开了全新视野,而且不仅仅在编程方面,还在于软件设计本身;对软件分析和软件体系结构来说,它也具有丰富的内涵。一起来看看 《C++设计新思维》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试