dio java,Flutter基础(十一)网络请求(Dio)与JSON数据解析

本文首发于微信公众号「后厂技术官」

前言

在Android开发中如果我们想要请求网络,可以使用HttpClent、HttpURLConnection,但在项目中一般都会使用OkHttp和Retrofit。在Flutter也是如此,系统提供了HttpClient,但在项目中一般会使用第三方库,比如http和Dio,如果你想找到更多的第三库,可以在pub.dartlang.org/ 上查找想要的库。本篇文章以Dio为例,另外还会介绍JSON数据解析方面的知识。

1.Dio的使用入门

Dio是一个强大的Dart Http请求库,支持拦截器,全局配置,FormData,请求取消,文件下载,超时等。

添加依赖

在pubspec.yaml中添加依赖。

dependencies:

dio: 2.1.7

官网给出了一个简单的例子:

import 'package:dio/dio.dart';

void getHttp() async{

try {

Response response = await Dio().get("http://liuwangshu.com");

print(response);

} catch (e) {

print(e);

}

}

如果想要发送一个GET请求:

Response response;

response=await dio.get("/test?id=3&name=liuwangshu")

print(response.data.toString());

// 请求参数也可以通过对象传递,上面的代码等同于:

response=await dio.get("/test",data:{"id":3,"name":"liuwangshu"})

print(response.data.toString());

发送一个POST 请求:

response=await dio.post("/test",data:{"id":3,"name":"liuwangshu"})

发送一个FormData:

FormData formData = new FormData.from({

"name": "liuwangshu",

"age": 18,

});

response = await dio.post("/info", data: formData);

2.Dio访问网络的例子import 'dart:convert';

import 'dart:io';

import 'package:dio/dio.dart';

import 'package:flutter/material.dart';

void main(){

runApp(MyApp());

}

class MyApp extends StatelessWidget{

@override

Widget build(BuildContext context){

return MaterialApp(

home: MyHomePage(),

);

}

}

class MyHomePage extends StatefulWidget{

MyHomePage({Key key}) : super(key: key);

@override

_MyHomePageState createState()=> _MyHomePageState();

}

class _MyHomePageState extends State{

var _ipAddress = 'Unknown';

_getIPAddress() async {//1

var url = 'https://httpbin.org/ip';

Dio _dio = Dio();

String result;

try {

var response = await _dio.get(url);//2

if (response.statusCode == HttpStatus.ok) {

var data= jsonDecode(response.toString());//3

result = data['origin'];

} else {

result =

'Error getting IP status ${response.statusCode}';

}

} catch (exception) {

result =exception.toString();

}

if (!mounted) return;

setState(() {

_ipAddress = result;//4

});

}

@override

Widget build(BuildContext context){

var spacer = SizedBox(height: 10.0);

return Scaffold(

body: Padding(

padding: EdgeInsets.all(100.0),

child: Column(

children: [

Text('IP地址为:'),

spacer,

Text('$_ipAddress'),

spacer,

RaisedButton(

onPressed: _getIPAddress,

child: Text('请求网络'),

),

],

),

),

);

}

}

async和await是Dart语言用来支持异步编程的关键字,注释1处的async关键字使得_getIPAddress方法变为了异步方法,注释2处的await关键字只能在异步方法中使用,它使得注释2处后面的代码等到get请求返回后再执行。

如果网络请求返回的状态码为200,就在注释3处进行Json解析,将结果赋值给result变量。

当我们点击界面上按钮时,会调用_getIPAddress方法,在注释4处将请求的结果赋值给_ipAddress并显示在Text中。

网络请求成功后,效果如下图。

5ab95d3f7282ebc34ade5f278a08f037.png

3.JSON数据解析

常用的JSON数据解析方式主要有三种,这里分别介绍下。

3.1 使用json.decode()方法

第2小节的例子用到的就是json.decode()方法,需要引入dart:convert库。json.decode() 方法会将 String类型数据解析成Map数据结构:Map, 取数据的格式为object[key]。

上面例子中返回的JOSN数据为:

{

"origin": "111.193.7.70, 111.193.7.70"

}

对于不复杂的JOSN数据使用json.decode()方法是一个不错的选择,但实际项目中的JOSN数据会复杂一些,如果每次取数据都用object[key],那么很容易出错。

3.2手动编写实体类

用一个model来保存数据,使得数据序列化。

我们可以新建一个ip.dart:

class Ip{

String origin;

Ip(this.origin);

Ip.fromJson(Map json) : origin = json['origin'];

Map toJson()=> {

"origin": origin,

};

}

然后修改main.dart:

import 'dart:convert';

import 'dart:io';

import 'package:dio/dio.dart';

import 'package:flutter/material.dart';

import 'model/ip.dart';

...

class _MyHomePageState extends State{

var _ipAddress = 'Unknown';

_getIPAddress() async {

var url = 'https://httpbin.org/ip';

Dio _dio = Dio();

String result;

try {

var response = await _dio.get(url);

if (response.statusCode == HttpStatus.ok) {

var data= jsonDecode(response.toString());

var ip=Ip.fromJson(data);//1

result = ip.origin;

}

...

}

...

}

注释1处通过Ip.fromJson就可以获取ip的实体,这样就可以完成赋值等操作了。

3.3 自动生成实体类

一般项目中Json数据会比较繁多,每次重复写实体类的模版代码显然枯燥无意义,可以使用一些工具来生成实体类。

比如使用网页自动生成: https://app.quicktype.io/ 。转换的实体类如下所示。

import 'dart:convert';

Ip ipFromJson(String str)=> Ip.fromJson(json.decode(str));

String ipToJson(Ip data)=> json.encode(data.toJson());

class Ip{

String origin;

Ip({

this.origin,

});

factory Ip.fromJson(Map json) => new Ip(

origin: json["origin"],

);

Map toJson()=> {

"origin": origin,

};

}

使用json_serializable

除了以上提到的工具,还可以使用json_serializable。

json_serializable是一个自动化的源代码生成器,可以方便的生成JSON实体类。

首先在pubspec.yaml加入如下依赖,

dependencies:

json_annotation: ^2.4.0

dev_dependencies:

build_runner: ^1.0.0

json_serializable: ^3.0.0

在AS的Terminal中运行flutter packages get命令,用来在项目中使用这些新的依赖项。

接着实现ip实体类。

import 'package:json_annotation/json_annotation.dart';

// ip.g.dart 将在我们运行生成命令后自动生成

part 'ip.g.dart';

//告诉生成器,这个类需要生成Model类

@JsonSerializable()

class Ip{

Ip(this.origin);

String origin;

factory Ip.fromJson(Map json) => _$IpFromJson(json);

Map toJson()=> _$IpToJson(this);

}

关键的在于@JsonSerializable(),它用于告诉生成器,Ip类是需要生成的Model类。在Terminal窗口运行如下命令生成ip.g.dart文件。

flutter packages pub run build_runner build

如何使用见3.2节就可以了,使用json_serializable可以让我们忽略Ip类中的任何手动JSON序列化 。源代码生成器会在同一个目录下生成Ip.g.dart,如下所示。

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'ip.dart';

// **************************************************************************

// JsonSerializableGenerator

// **************************************************************************

Ip _$IpFromJson(Map json) {

return Ip(json['origin'] as String);

}

Map _$IpToJson(Ip instance) =>

{'origin': instance.origin};

该文件有着必需的序列化逻辑,目前Flutter官方推荐的就是使用json_serializable。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flutter 中进行网络请求可以使用 `http` 或者 `dio` 等第三方库。 #### 使用 http 首先,在 `pubspec.yaml` 文件中添加依赖: ``` dependencies: http: ^0.13.3 ``` 然后,在需要进行网络请求的地方引入 `http` 库: ```dart import 'package:http/http.dart' as http; ``` 接下来,可以使用 `http.get` 或者 `http.post` 方法进行 GET 或者 POST 请求。例如,使用 GET 方法请求一个 JSON 数据: ```dart Future<void> fetchAlbum() async { final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1')); if (response.statusCode == 200) { // 请求成功,处理响应数据 print(response.body); } else { // 请求失败,处理错误信息 print('请求失败,状态码为 ${response.statusCode}'); } } ``` #### 使用 dio 首先,在 `pubspec.yaml` 文件中添加依赖: ``` dependencies: dio: ^4.0.0 ``` 然后,在需要进行网络请求的地方引入 `dio` 库: ```dart import 'package:dio/dio.dart'; ``` 接下来,可以使用 `Dio` 实例进行 GET 或者 POST 请求。例如,使用 GET 方法请求一个 JSON 数据: ```dart Future<void> fetchAlbum() async { final dio = Dio(); final response = await dio.get('https://jsonplaceholder.typicode.com/albums/1'); if (response.statusCode == 200) { // 请求成功,处理响应数据 print(response.data); } else { // 请求失败,处理错误信息 print('请求失败,状态码为 ${response.statusCode}'); } } ``` 以上就是 Flutter 中进行网络请求的基本方法。需要注意的是,网络请求需要在异步环境下进行,因此需要使用 `async/await` 或者 `Future.then` 等方法处理异步操作。同时,还需要处理请求成功和请求失败的情况,以及错误信息的展示和处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值