dart入门指南 (6)

关闭连接

import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:flutter/cupertino.dart'; // 这里封装了一个发get请求的方法,将返回的json字符串反序列化 Future<Map<String, dynamic>> httpGet( {@required String url, Map<String, dynamic> headers = const {}, Map<String, dynamic> params = const {}, int timeout = 10}) async { // 创建HttpClient实例 HttpClient client = HttpClient(); // 我在本地启动一个代理服务,这样方便抓包,没有代理服务可以去掉 client.findProxy = (uri) { // 如果需要过滤uri,可以手动判断 return "PROXY 127.0.0.1:8888"; }; // 超时时间设置 client.connectionTimeout = Duration(seconds: timeout); // 通过url(包括协议 主机 路径)创建Uri对象, 便于获取url的各个部分 Uri uri = Uri.parse(url); // 使用getUrl创建 HttpClientRequest对象 HttpClientRequest httpClientRequest = await client.getUrl(Uri( scheme: uri.scheme, host: uri.host, path: uri.path, queryParameters: params)); // 加上自定义header headers.forEach((key, value) { httpClientRequest.headers.add(key, value); }); // 调用HttpClientRequest的close得到HttpClientResponse HttpClientResponse httpClientResponse = await httpClientRequest.close(); // 使用特定字符集解码 var str = await httpClientResponse.transform(utf8.decoder).join(); // 将字符串序列化为Map, 这个将在后文详解 Map<String, dynamic> map = jsonDecode(str); // 关闭连接 client.close(force: false); return map; } void main() async { Map<String, dynamic> map = await httpGet( url: 'http://t.weather.sojson.com/api/weather/city/101030100', headers: <String, dynamic>{ 'custom_header': 'customheader', }, params: <String, dynamic>{ "version": 'v1', 'cityid': '101120201', 'city': '青岛' }); print(map); }

以上代码简单封装了一个发get请求的方法,get请求的参数是带在url上的,而post则不同,post的参数通常是在body中,下面演示如何发一个post请求, 数据格式采用json, 表单格式的类似,修改application即可。

void main() async { HttpClient client = HttpClient(); // 本地搭了一个服务,用于测试 HttpClientRequest httpClientRequest = await client.postUrl(Uri.parse('http://127.0.0.1:3000/users/save')); // 关键步骤,告诉服务器请求参数格式 httpClientRequest.headers.contentType = new ContentType("application", "json", charset: "utf-8"); // 关键步骤,写数据到body httpClientRequest.write(jsonEncode({"name":'lily', 'age': 20})); HttpClientResponse httpClientResponse = await httpClientRequest.close(); var str = await httpClientResponse.transform(utf8.decoder).join(); Map<String, dynamic> map = jsonDecode(str); print(map); }

还有关于上传文件的内容,本文篇幅过长了,后面再写一个。

http

我们发现使用原生的HttpClient来发请求还是比较麻烦的,我们可以使用package:http/http.dart这个包可以大大简化开发。包安装可以参考上文模块化部分

import 'package:http/http.dart' as http; void main() async { // 演示post请求 var url = 'http://127.0.0.1:3000/users/save'; var response = await http.post(url, body: {'name': 'lily', 'age': '20'}); print('Response status: ${response.statusCode}'); print('Response body: ${response.body}'); // 演示get请求 var response2 = await http.get('http://127.0.0.1:3000?a=1',); print(response2.body); }

可以发现使用package:http/http.dart极其方便。

json序列化与反序列化

json是一种非常灵活的数据交换格式。

json序列化与反序列化通俗讲就是将 语言定义的非字符串类型(比如java中的实体类,dart中的Map)转换为json字符串,便于传输和存储,这是序列化;反序列化则是这个逆过程,方便操作数据。

在java中一般使用阿里的fastjson做json的序列化与反序列化;

在js使用JSON.stringify()、JSON.parse()做序列化与反序列化。

在dart中json序列化与反序列化有两种方式:

一是 使用内置库dart:convert的jsonDecode和jsonEncode

二是 使用package:json_serializable,这个库跟下问所说的第二种方法差不多,只不过他会自动帮你生成下边会讲到的那些样板代码,这里不进行详细介绍了。

使用dart:convert

不关注类型,直接用动态类型,这种方式会导致无法错类型检查,可能不安全,好处是简单,不用写实体类

import 'dart:convert'; void main() async { String jsonString = '[{"name":"name1","age":1},{"name":"name2","age":2}]'; List list = jsonDecode(jsonString); list.forEach((item) { print(item['name']); }); String jsonString2 = jsonEncode(list); print(jsonString2); }

使用类型转换,在实体类定义一些转换规则,好处是可以有静态类型检查,缺点是比较麻烦

import 'dart:convert'; class User { String name; int age; User(this.name, this.age); // 将map转为User User.fromJson(Map<String, dynamic> json) { name = json['name']; age = json['age']; } // 将User转成map Map<String, dynamic> toJson() => { 'name': name, 'age': age, }; } void main() async { List<User> list = List(); list.add(User('name1', 1)); list.add(User('name2', 2)); // 这里会自动调用toJson String str = jsonEncode(list); print(str.runtimeType); // String print(str); // [{"name":"name1","age":1},{"name":"name2","age":2}] // 这里希望反序列化为List<User> 但是尚未找到方法, // 网上文档基本就是翻译翻译官方文档,官网也没找到解决方案 List userList = jsonDecode(str); userList.forEach((item) { // 这里不得不手动强转 User u = User.fromJson(item); print(u.name); }); // name1 // name2 }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfyzy.html