Flutter中的HTTP网络请求与JSON序列化

Flutter中的HTTP网络请求与JSON序列化Http请求查阅Flutter的相关资料,关于网络请求库,既可以用dart:io包中提供的HttpClient,也可以用flutterchina推荐的三方封装的请求库dio来发起网络请求,还可以用Flutter官方介绍的http。下分别介绍这几种发起网络请求的库:1.dart自带的HttpClient查看详情https://flutterchina.club/netwo…

Http 请求

查阅Flutter的相关资料,关于网络请求库,既可以用 dart:io 包中提供的HttpClient,也可以用 flutterchina 推荐的三方封装的请求库 dio 来发起网络请求,还可以用Flutter 官方介绍的 http。

下分别介绍这几种发起网络请求的库:

1.dart自带的HttpClient

查看详情 https://flutterchina.club/networking/
HttpClient 位于dart:io,所以要创建一个HttpClient , 我们需要添加一个导入:

import 'dart:io';

var httpClient = new HttpClient();

该 client 支持常用的HTTP操作, such as GET, POST, PUT, DELETE.

示例get:

get() async { 
   
  var httpClient = new HttpClient();
  var uri = new Uri.http(
      'example.com', '/path1/path2', { 
   'param1': '42', 'param2': 'foo'});
// httpClient.post(host, port, path)
  var request = await httpClient.getUrl(uri);
  var response = await request.close();
  var responseBody = await response.transform(utf8.decoder).join();
  print(responseBody);
}

2.Flutter 官方介绍的http

查看详情 https://flutter.dev/docs/cookbook/networking/fetch-data

dependencies:
  http: <latest_version>

发起请求

Future<Post> fetchPost() async { 
   
  final response =
      await http.get('https://jsonplaceholder.typicode.com/posts/1');

  if (response.statusCode == 200) { 
   
    // If server returns an OK response, parse the JSON
    return Post.fromJson(json.decode(response.body));
  } else { 
   
    // If that response was not OK, throw an error.
    throw Exception('Failed to load post');
  }
}

3.flutterchina 推荐的三方库dio

查看详情 https://github.com/flutterchina/dio/blob/master/README-ZH.md

添加依赖

dependencies:
dio: ^2.1.x  // 请使用pub上2.1分支的最新版本

简单示例

import 'package:dio/dio.dart';
void getHttp() async { 
   
try { 
   
  Response response = await Dio().get("http://www.baidu.com");
  print(response);
} catch (e) { 
   
  print(e);
}
}

JSON和序列化

针对服务端返回的数据,先将其进行反序列化,然后使用对象是比较正规的方式,将json 反序列化成对象,有两种方式:手动解析json或者使用三方序列化工具

注意:这里服务端返回的数据首先要转换成json 格式,如果使用dio 发起的请求,那么默认的返回类型就已经是json, 如果其他方式发起的请求 返回可能需要去转格式。

手动解析json

Map<String, dynamic> user = json.decode(json);

print('Howdy, ${user['name']}!');
print('We sent the verification link to ${user['email']}.');

在模型类中序列化JSON

我们可以通过引入一个简单的模型类(model class)来解决前面提到的问题,我们称之为User。在User类内部,我们有:

一个User.fromJson 构造函数, 用于从一个map构造出一个 User实例
一个toJson 方法, 将 User 实例转化为一个map.

这样,调用代码现在可以具有类型安全、自动补全字段(name和email)以及编译时异常。如果我们将拼写错误或字段视为int类型而不是String, 那么我们的应用程序就不会通过编译,而不是在运行时崩溃。

user.dart

class User { 
   
  final String name;
  final String email;

  User(this.name, this.email);

  User.fromJson(Map<String, dynamic> json)
      : name = json['name'],
        email = json['email'];

  Map<String, dynamic> toJson() =>
    { 
   
      'name': name,
      'email': email,
    };
}

现在,序列化逻辑移到了模型本身内部。采用这种新方法,我们可以非常容易地反序列化user。

Map userMap = JSON.decode(json);
var user = new User.fromJson(userMap);

print('Howdy, ${user.name}!');
print('We sent the verification link to ${user.email}.');

要序列化一个user,我们只是将该User对象传递给该JSON.encode方法。我们不需要手动调用toJson这个方法,因为JSON.encode已经为我们做了。

String json = JSON.encode(user);

json_serializable序列化JSON

详情查看 https://github.com/dart-lang/json_serializable/tree/master/example

pubspec.yaml 添加依赖

dependencies:
  # Your other regular dependencies here
  json_annotation: ^2.0.0

dev_dependencies:
  # Your other dev_dependencies here
  build_runner: ^1.0.0
  json_serializable: ^2.0.0

在您的项目根文件夹中运行 flutter packages get (或者在编辑器中点击 “Packages Get”) 以在项目中使用这些新的依赖项.

以json_serializable的方式创建model类

让我们看看如何将我们的User类转换为一个json_serializable。为了简单起见,我们使用前面示例中的简化JSON model。

user.dart

import 'package:json_annotation/json_annotation.dart';

// user.g.dart 将在我们运行生成命令后自动生成
part 'user.g.dart';

///这个标注是告诉生成器,这个类是需要生成Model类的
@JsonSerializable()

class User{ 
   
  User(this.name, this.email);

  String name;
  String email;
  //不同的类使用不同的mixin即可
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

有了这个设置,源码生成器将生成用于序列化name和email字段的JSON代码。

如果需要,自定义命名策略也很容易。例如,如果我们正在使用的API返回带有_snake_case_的对象,但我们想在我们的模型中使用_lowerCamelCase_, 那么我们可以使用@JsonKey标注:

/// Tell json_serializable that "registration_date_millis" should be
/// mapped to this property.
@JsonKey(name: 'registration_date_millis')
final int registrationDateMillis;

运行代码生成程序
json_serializable第一次创建类时,您会看到与下图类似的错误。
在这里插入图片描述
这些错误是完全正常的,这是因为model类的生成代码还不存在。为了解决这个问题,我们必须运行代码生成器来为我们生成序列化模板。
有两种运行代码生成器的方法:

一次性生成
通过在我们的项目根目录下运行flutter packages pub run build_runner build,我们可以在需要时为我们的model生成json序列化代码。

持续生成
使用_watcher_可以使我们的源代码生成的过程更加方便。它会监视我们项目中文件的变化,并在需要时自动构建必要的文件。我们可以通过flutter packages pub run
build_runner watch在项目根目录下运行来启动_watcher_。

只需启动一次观察器,然后并让它在后台运行,这是安全的。

使用json_serializable模型

Map userMap = JSON.decode(json);
var user = new User.fromJson(userMap);

序列化也一样。调用API与之前相同。

String json = JSON.encode(user);

有了json_serializable,我们可以在User类上忘记任何手动的JSON序列化 。源代码生成器创建一个名为user.g.dart的文件,它具有所有必需的序列化逻辑。

还有一个网页版在线将json-> dart

https://javiercbk.github.io/json_to_dart/

这里有我学习Flutter过程中的一个Demo,会持续更新Demo的内容,对Flutter 有兴趣的朋友可以一起学习。
https://github.com/CodingForAndroid/flutter_new

欢迎爱学习的小伙伴加群一起进步:230274309 今天的文章Flutter中的HTTP网络请求与JSON序列化分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/30207.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注