Flutter 联网和JSON转换成Bean

Flutter 联网和JSON转换成Bean

Flutter的联网分为HttpClient和dio两种。HttpClient是dart io中的HttpClient发起的请求,但HttpClient本身功能较弱,很多常用功能都不支持。dart io官网文档.
dio是一个强大的Dart Http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时等…dio github地址.
JSON类型数据的转换分为两种:手动序列化和反序列化 dart:convert和通过代码生成自动序列化和反序列化json_serializable。
手动JSON序列化是指使使用dart:convert中内置的JSON解码器。它将原始JSON字符串传递给JSON.decode() 方法,然后在返回的Map中查找所需的值。 它没有外部依赖或其它的设置,对于小项目很方便。
当您的项目变大时,手动编写序列化逻辑可能变得难以管理且容易出错。如果您在访问未提供的JSON字段时输入了一个错误的字段,则您的代码将会在运行时会引发错误。

HttpClient和dart convert序列化数据

String url = "https://httpbin.org/ip";
    var httpClient = HttpClient();
    String result;
    try {
     var request =  await httpClient.getUrl(Uri.parse(url));
     var response = await request.close();
     if(response.statusCode == HttpStatus.ok){
       var jsonStr = await response.transform(utf8.decoder).join();
       var date = json.decode(jsonStr);
       result = date['origin'];
     }else{
       result = 'Error getting IP address:\nHttp status ${response.statusCode}';
     }
    }catch(Exception){
      result = 'Failed getting IP address';
    }

这段代码用的是HttpClient和内连序列化JSON.
下面介绍。在模型类中序列化JSON:
1.先创建一个IpBean用于接收返回的数据

class IpBean{
  String origin;
  IpBean({this.origin});
  IpBean.fromJson(Map<String, dynamic> json)
      : origin = json['origin'];
  
  Map<String, dynamic> toJson() =>
      {
        'origin': origin,
      };
}

2.进行序列化:

 var jsonStr = await response.transform(utf8.decoder).join();
 IpBean ipBean = new IpBean.fromJson(ipMap);

3.反序列化:

       String ipStr = json.encode(ipBean);

这个地方可以查看Flutter 中文官网地址.

dio请求库和json_serializable序列化数据

1.导入请求库

dependencies:
 flutter:
    sdk: flutter
  json_annotation: ^1.2.0 
  dio: ^1.0.6
  dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner: ^1.1.1
  json_serializable: ^1.3.0

导入这四个库就可以开始愉快的联网请求了

2.创建build.yaml文件。
在项目的根目录下新建一个build.yaml的文件用于构件项目时自动生成代码:
build.yaml代码

targets:
  $default:
    builders:
      json_serializable:
        options:
          # Options configure how source code is generated for every
          # `@JsonSerializable`-annotated class in the package.
          #
          # The default value for each is listed.
          #
          # For usage information, reference the corresponding field in
          # `JsonSerializableGenerator`.
          any_map: false
          checked: false
          create_factory: true
          create_to_json: true
          disallow_unrecognized_keys: false
          explicit_to_json: false
          field_rename: none
          generate_to_json_function: true
          include_if_null: true
          nullable: true
          use_wrappers: false

3.准备好要序列化的Bean类

import 'package:json_annotation/json_annotation.dart';
part 'ImageBean.g.dart';

@JsonSerializable()
class ImageBean{

  ImageBean(this.url);
  String url;
  factory ImageBean.fromJson(Map<String, dynamic> json) => _$ImageBeanFromJson(json);
  Map<String, dynamic> toJson() => _$ImageBeanToJson(this);
}


part 'ImageListBean.g.dart';
@JsonSerializable()
class ImageListBean{

  ImageListBean(this.results,this.error);
  List<ImageBean> results;
  bool error;
  factory ImageListBean.fromJson(Map<String, dynamic> json) => _$ImageListBeanFromJson(json);
  Map<String, dynamic> toJson() => _$ImageListBeanToJson(this);
}

第一次创建类时,您会看到与下图类似的错误
Flutter 联网和JSON转换成Bean_第1张图片
这些错误是完全正常的,这是因为model类的生成代码还不存在。为了解决这个问题,我们必须运行代码生成器来为我们生成序列化模板。

4.运行代码生成器
有两种运行代码生成器的方法:
一次性生成
通过在我们的项目根目录下运行flutter packages pub run build_runner build,我们可以在需要时为我们的model生成json序列化代码。 这触发了一次性构建,它通过我们的源文件,挑选相关的并为它们生成必要的序列化代码。
虽然这非常方便,但如果我们不需要每次在model类中进行更改时都要手动运行构建命令的话会更好。

持续生成
使用_watcher_可以使我们的源代码生成的过程更加方便。它会监视我们项目中文件的变化,并在需要时自动构建必要的文件。我们可以通过flutter packages pub run
build_runner watch在项目根目录下运行来启动_watcher_。
只需启动一次观察器,然后并让它在后台运行,这是安全的。
5.使用dio库发送网络请求,并完成序列化

print("------------------------开始请求--------------------------------------");
    Dio dio = Dio();
    dio.options.baseUrl = "https://gank.io/";
    dio.options.connectTimeout = 5000;
    dio.options.receiveTimeout = 5000;
    dio.options.responseType = ResponseType.JSON;
    dio.options.path = "/api/data/福利/10/1";
    dio.options.headers = {
      'user-agent': 'dio',
      'from': "dio"
    };
    Response response = await dio.get("/api/data/福利/10/1");
    var data = response.data;
    print(data);
    print(response.data is String);
    ImageListBean image = ImageListBean.fromJson(data);
    print("------------------------请求结束---------------------------------------");

这样就完成了一次网络请求。
参考文档
Flutter中文网 在Flutter中发起HTTP网络请求
Flutter中文网 JSON和序列化

你可能感兴趣的:(Flutter)