前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter开发-网络请求与JSON转换

Flutter开发-网络请求与JSON转换

作者头像
码客说
发布2020-05-14 16:49:06
1.7K0
发布2020-05-14 16:49:06
举报
文章被收录于专栏:码客

网络请求

添加依赖

代码语言:javascript
复制
dependencies:
  dio: ^3.0.9

导入并创建dio实例:

代码语言:javascript
复制
import 'package:dio/dio.dart';
Dio dio =  Dio();

示例

发起 GET 请求 :

代码语言:javascript
复制
Response response;
response=await dio.get("/test?id=12&name=wendu")
print(response.data.toString());

对于GET请求我们可以将query参数通过对象来传递,上面的代码等同于:

代码语言:javascript
复制
response=await dio.get("/test",queryParameters:{"id":12,"name":"wendu"})
print(response);

发起一个 POST 请求:

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

发起多个并发请求:

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

下载文件:

代码语言:javascript
复制
response=await dio.download("https://www.google.com/",_savePath);

发送 FormData:

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

如果发送的数据是FormData,则dio会将请求header的contentType设为“multipart/form-data”。

通过FormData上传多个文件:

代码语言:javascript
复制
FormData formData = new FormData.from({
   "name": "wendux",
   "age": 25,
   "file1": new UploadFileInfo(new File("./upload.txt"), "upload1.txt"),
   "file2": new UploadFileInfo(new File("./upload.txt"), "upload2.txt"),
     // 支持文件数组上传
   "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)

值得一提的是,dio内部仍然使用HttpClient发起的请求,所以代理、请求认证、证书校验等和HttpClient是相同的,我们可以在onHttpClientCreate回调中设置,例如:

代码语言:javascript
复制
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
    //设置代理 
    client.findProxy = (uri) {
      return "PROXY 192.168.1.2:8888";
    };
    //校验证书
    httpClient.badCertificateCallback=(X509Certificate cert, String host, int port){
      if(cert.pem==PEM){
      return true; //证书一致,则允许发送数据
     }
     return false;
    };   
  };

注意,onHttpClientCreate会在当前dio实例内部需要创建HttpClient时调用,所以通过此回调配置HttpClient会对整个dio实例生效,如果你想针对某个应用请求单独的代理或证书校验策略,可以创建一个新的dio实例即可。

JSON解析

读取本地JSON文件

比如要读取项目根目录下的assets/person.json

首先要在 pubspec.yaml 中做如下配置:

代码语言:javascript
复制
flutter:
    uses-material-design:  true
    # 资源文件配置
    assets:
        -  assets/person.json

导入如下几个依赖库:

代码语言:javascript
复制
// 使用该库中的 rootBundle 对象来读取 perosn.json 文件
import 'package:flutter/services.dart';  
// json
import 'dart:convert';  
// 异步 Future
import 'dart:async';

实体类

代码语言:javascript
复制
class Person {
  String name;
  int age;
  double height;

  Person({this.name, this.age, this.height});

  factory Person.fromJson(Map<String, dynamic> json) {
    return Person(name: json['name'], age: json['age'], height: json['height']);
  }
}

读取转换

代码语言:javascript
复制
import 'package:flutter/services.dart';
import 'dart:convert';
import 'dart:async';
import '../models/person.dart';

// 读取 assets 文件夹中的 person.json 文件
Future<String> _loadPersonJson() async {
  return await rootBundle.loadString('assets/person.json');
}

// 将 json 字符串解析为 Person 对象
Future<Person> decodePerson() async {
  // 获取本地的 json 字符串
  String personJson = await _loadPersonJson();

  // 解析 json 字符串,返回的是 Map<String, dynamic> 类型
  final jsonMap = json.decode(personJson);

  print('jsonMap runType is ${jsonMap.runtimeType}');

  Person person = Person.fromJson(jsonMap);

  print(
      'person name is ${person.name}, age is ${person.age}, height is ${person.height}');

  return person;
}

JSON和Map互转

添加引用

代码语言:javascript
复制
import 'dart:convert';

JSON字符串转Map

代码语言:javascript
复制
Map<String, dynamic> user = JSON.decode(json);

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

对象转JSON字符串

代码语言:javascript
复制
String json = JSON.encode(user);

JSON字符串转Model类

简单对象转换

json

代码语言:javascript
复制
{
    "name":  "jack",
    "age":  18,
    "height":  175.0
}

实体类

代码语言:javascript
复制
class Person {
  String name;
  int age;
  double height;

  Person({this.name, this.age, this.height});

  factory Person.fromJson(Map<String, dynamic> json) {
    return Person(name: json['name'], age: json['age'], height: json['height']);
  }
}

调用

代码语言:javascript
复制
final jsonMap = json.decode(personJson);
print('jsonMap runType is ${jsonMap.runtimeType}');
Person person = Person.fromJson(jsonMap);

输出如下

代码语言:javascript
复制
jsonMap runType is _InternalLinkedHashMap<String, dynamic>

可以看出 json.decode(personJson) 方法返回的类型为 _InternalLinkedHashMap ,意思就是这个 Map 的 key 为 String 类型,而 value 的类型为 dynamic 的,也就是动态的

数组的转换

代码语言:javascript
复制
[
  {
    "id": 1,
    "name": "Jack"
  },
  {
    "id": 2,
    "name": "Rose"
  }
]

实体类

代码语言:javascript
复制
class MemberList {  
  List<Member> memberList;  
  
  MemberList({this.memberList});  
  
  factory MemberList.fromJson(List<dynamic> listJson) {  
  
  List<Member> memberList =  
        listJson.map((value) => Member.fromJson(value)).toList();  
  
  return MemberList(memberList: memberList);  
  }  
}  
  
class Member {  
  int id;  
  String name;  
  
  Member({this.id, this.name});  
  
  factory Member.fromJson(Map<String, dynamic> json) {  
  return Member(id: json['id'], name: json['name']);  
  }  
}

调用

代码语言:javascript
复制
List<dynamic> list = json.decode(memberListJson);
MemberList memberList = MemberList.fromJson(list);
memberList.memberList
    .forEach((member) => print('member name is ${member.name}'));

带有数组的对象转换

代码语言:javascript
复制
{
    "name": "China",
    "cities": [
        "Beijing",
        "Shanghai"
    ]
}

实体类

代码语言:javascript
复制
class Country {  
  String name;  
  List<String> cities;  
  
  Country({this.name, this.cities});  
  
  factory Country.fromJson(Map<String, dynamic> json) {
    var originList = json['cities'];
    List<String> cityList = new List<String>.from(originList);
    return Country(name: json['name'], cities: cityList);
  } 
}

调用

代码语言:javascript
复制
Map<String, dynamic> jsonMap = json.decode(countryJson);
Country country = Country.fromJson(jsonMap);

复杂的对象数组嵌套

json

代码语言:javascript
复制
{
  "id": "0302",
  "class_name": "三年二班",
  "students": [
    {
      "name": "叶湘伦",
      "sex": "男"
    },
    {
      "name": "路小雨",
      "sex": "女"
    }
  ]
}

实体

代码语言:javascript
复制
class ClassInfo {
  String id;
  String name;
  List<Student> studentList;

  ClassInfo({this.id, this.name, this.studentList});

  factory ClassInfo.fromJson(Map<String, dynamic> json) {  
      final originList = json['students'] as List;  
      List<Student> studentList =  
          originList.map((value) => Student.fromJson(value)).toList();  
      return ClassInfo(id: json['id'], name: json['class_name'], studentList: studentList);  
  }
}

class Student {
  String name;
  String sex;

  Student({this.name, this.sex});

  factory Student.fromJson(Map<String, dynamic> json) {
    return Student(name: json['name'], sex: json['sex']);
  }
}

调用

代码语言:javascript
复制
Map<String, dynamic> jsonMap = json.decode(classInfoJson);

ClassInfo classInfo = ClassInfo.fromJson(jsonMap);
classInfo.studentList
    .forEach((student) => print('student name is ${student.name}'));

使用插件生成实体类

FlutterJsonBeanFactory插件

除了上面的方式外,我们还可以使用FlutterJsonBeanFactory插件来辅助生成Bean类。 安装FlutterJsonBeanFactory插件很简单,

以Android Studio为例,

依次选择【Android Studio】->【Settings】->【Plugins】,然后搜索FlutterJsonBeanFactory插件安装即可

使用方式

在要生成文件的文件夹上右键New -> dart bean class File from JSON

该插件转换要求JSON的最外层为对象,不能为数组,为数组时无法转换。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-05-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 网络请求
  • JSON解析
    • 读取本地JSON文件
      • JSON和Map互转
        • JSON字符串转Model类
          • 简单对象转换
          • 数组的转换
          • 带有数组的对象转换
          • 复杂的对象数组嵌套
        • 使用插件生成实体类
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档