首先将依赖加上

1.巧妇难为无米之炊

首先我们需要找写测试的url链接,有一个好地方,那就是Github提供了很多api
但在此之前我们需要先行处理一些事,比如注册Github账号,获取一个token
下面的Github账号是我专门为Flutter准备的,token值就不加密了,大家不要乱玩。


1.1:如何获取token

小头像-->Settings-->Developer settings -->Personal access tokens-->Generate new token


1.2:如何通过post请求在你的github项目中添加一个文件

api:https://api.github.com/repos/用户名/项目名/contents/文件路径?access_token=token值
请求头:Content-Type=application/json,请求体如下,注意文件内容需要用base64
可以用wanandroid里的工具转化,该请求的其他参数可以详见Github的相应api

{"message": "commit from toly ",//提交信息"content": "aGVsbG8="//数据内容
}
复制代码
  • Flutter中发送put请求,在github项目中添加一个文件
import 'package:http/http.dart' as client;main() {put();
}void put() {var baseUrl="https://api.github.com/";var operate="repos/toly-flutter/flutter_journey/contents/";var path="http-put-file.txt";var params="?access_token=4514388836f6da9f6c6cf7ba0721f2a6d1e89528";//请求参数var api =baseUrl+operate+path+params;//urlMap<String ,String> headers = {"Content-Type":"application/json"};//请求头var reqBody="""{"message": "commit from commit from toly","content": "aGVsbG8="}""";//请求体client.put(api,headers:headers,body: reqBody).then((rep){print(rep.statusCode);print(rep.body);});
}
复制代码

注,Dart中将字符串转换base64可以:base64Encode(utf8.encode("hello"));


1.3:通过put请求修改一个github文件

api:https://api.github.com/repos/用户名/项目名/contents/文件路径?access_token=token值
请求头:Content-Type=application/json,请求体如下,注意文件内容需要用base64
关于sha值,在添加的时候,响应体中有,见上图。每次修改也会返回新的sha值

{"message": "update by toly ",//提交信息"content": "aGVsbG8="//数据内容"sha":"文件所对应的sha值"
}
复制代码
  • Flutter中发送put请求,在github项目中修改一个文件
void update() {var baseUrl="https://api.github.com/";var operate="repos/toly-flutter/flutter_journey/contents/";var path="http-put-file.txt";var params="?access_token=4514388836f6da9f6c6cf7ba0721f2a6d1e89528";//请求参数var api =baseUrl+operate+path+params;//urlMap<String ,String> headers = {"Content-Type":"application/json"};//请求头var reqBody="""{"message": "update by toly","content": "5byg6aOO5o2354m554OI","sha":"b6fc4c620b67d95f953a5c1c1230aaab5db5a1b0"}""";//请求体client.put(api,headers:headers,body: reqBody).then((rep){print(rep.statusCode);print(rep.body);});
}
复制代码

1.4:通过delete请求删除一个github文件

api:https://api.github.com/repos/用户名/项目名/contents/文件路径?access_token=token值
请求头:Content-Type=application/json,可以要当前文件的sha值

{"message": "delete by toly ",//提交信息"sha":"文件所对应的sha值"
}
复制代码

http库的delete请求居然不能加请求体?!这里用PostMan演示一下


1.5:用post提交一个issue

api:https://api.github.com/repos/用户名/项目名/issues?access_token=token值
请求头:Content-Type=application/json,可以要当前文件的sha值

{"title": "一起来Flutter之旅吧","body": "Flutter,大家感觉怎么样?应该不难吧!"
}
复制代码
  • Flutter中发送post请求,在github项目中添加一条issue
void post() {var baseUrl="https://api.github.com/";var operate="repos/toly-flutter/flutter_journey/issues";var params="?access_token=4514388836f6da9f6c6cf7ba0721f2a6d1e89528";//请求参数var api =baseUrl+operate+params;//urlMap<String ,String> headers = {"Content-Type":"application/json"};//请求头var reqBody="""
{"title": "一起来Flutter之旅吧","body": "Flutter,大家感觉怎么样?应该不难吧!"
}""";//请求体client.post(api,headers:headers,body: reqBody).then((rep){print(rep.statusCode);print(rep.body);});
}
复制代码

1.6:使用get请求获取一个issue

api:https://api.github.com/repos/用户名/项目名/issues/第几个?access_token=token值

void get(){//GET /repos/:owner/:repo/issues/:issue_numbervar baseUrl="https://api.github.com/";var operate="repos/toly-flutter/flutter_journey/issues/1";var params="?access_token=4514388836f6da9f6c6cf7ba0721f2a6d1e89528";//请求参数var api =baseUrl+operate+params;//urlclient.get(api).then((rep){print(rep.statusCode);print(rep.body);});
}
复制代码

好了,Http的几种常用的请求方式基本都会了吧。


2. Json的解析

2.0:简介

Dart中的Map<String,String>对象和Json非常相似,所以可以用其作为转换媒介
通过convert包中的json.decode方法,可以将Json字符串转化成一个Map对象
在实体类中可以根据这个Map对象的属性对实体类进行实例化。

import 'dart:convert';main() {String jsonStr = """
{"name":"Flutter之旅","author":"张风捷特烈"
}
""";var book = Book.fromMap(json.decode(jsonStr));print(book.name);//Flutter之旅print(book.author);//张风捷特烈
}class Book {String name;String author;Book.fromMap(Map<String, dynamic> json) {//根据Map穿件实例name = json["name"];author = json["author"];}
}
复制代码

2.1: 获取json

Github的https://api.github.com/users/用户名可以获取用户基本信息
这里就先解析我的https://api.github.com/users/toly1994328

{"login": "toly1994328","id": 26687012,"node_id": "MDQ6VXNlcjI2Njg3MDEy","avatar_url": "https://avatars3.githubusercontent.com/u/26687012?v=4","gravatar_id": "","url": "https://api.github.com/users/toly1994328","html_url": "https://github.com/toly1994328","followers_url": "https://api.github.com/users/toly1994328/followers","following_url": "https://api.github.com/users/toly1994328/following{/other_user}","gists_url": "https://api.github.com/users/toly1994328/gists{/gist_id}","starred_url": "https://api.github.com/users/toly1994328/starred{/owner}{/repo}","subscriptions_url": "https://api.github.com/users/toly1994328/subscriptions","organizations_url": "https://api.github.com/users/toly1994328/orgs","repos_url": "https://api.github.com/users/toly1994328/repos","events_url": "https://api.github.com/users/toly1994328/events{/privacy}","received_events_url": "https://api.github.com/users/toly1994328/received_events","type": "User","site_admin": false,"name": "张风捷特烈(toly)","company": "捷特王国","blog": "http://www.toly1994.com","location": "China","email": null,"hireable": null,"bio": "The king of coder.","public_repos": 64,"public_gists": 0,"followers": 238,"following": 9,"created_at": "2017-03-26T09:55:25Z","updated_at": "2019-07-15T08:05:52Z"
}
复制代码

2.2:实体类的生成

你也可以一点一点写出这个实体类,不过推荐用生成的方法,比较有时候字段太多,比较费劲
这里给一个用起来还不错的地方JSON to Dart,有时间自己写个转换插件来玩玩

class User {String login;int id;String nodeId;String avatarUrl;String gravatarId;String url;String htmlUrl;String followersUrl;String followingUrl;String gistsUrl;String starredUrl;String subscriptionsUrl;String organizationsUrl;String reposUrl;String eventsUrl;String receivedEventsUrl;String type;bool siteAdmin;String name;String company;String blog;String location;String email;String hireable;String bio;int publicRepos;int publicGists;int followers;int following;String createdAt;String updatedAt;User.fromJson(Map<String, dynamic> json) {login = json['login'];id = json['id'];nodeId = json['node_id'];avatarUrl = json['avatar_url'];gravatarId = json['gravatar_id'];url = json['url'];htmlUrl = json['html_url'];followersUrl = json['followers_url'];followingUrl = json['following_url'];gistsUrl = json['gists_url'];starredUrl = json['starred_url'];subscriptionsUrl = json['subscriptions_url'];organizationsUrl = json['organizations_url'];reposUrl = json['repos_url'];eventsUrl = json['events_url'];receivedEventsUrl = json['received_events_url'];type = json['type'];siteAdmin = json['site_admin'];name = json['name'];company = json['company'];blog = json['blog'];location = json['location'];email = json['email'];hireable = json['hireable'];bio = json['bio'];publicRepos = json['public_repos'];publicGists = json['public_gists'];followers = json['followers'];following = json['following'];createdAt = json['created_at'];updatedAt = json['updated_at'];}
复制代码

2.3.网络请求+json的使用

现在完全可以将以前写的界面改一改,然后用Github获取的数据填充进去
这里只是简单展示一下,说明网络数据和布局界面的对接,并没有做得太精细
GithubPanel就是以前写得界面稍微改装一下,这里代码就不贴了。

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as client;
import 'day6/github_panel.dart';
import 'day6/user.dart';void main() {var baseUrl = "https://api.github.com/";var operate = "users/";var name = "toly1994328";var api = baseUrl + operate + name; //urlclient.get(api).then((rep) {var user = User.fromJson(json.decode(rep.body));
print(user.avatarUrl);var scaffold = Scaffold(appBar: AppBar(title: Text("Flutter之旅"),),body: GithubPanel(user: user,));var app = MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: scaffold,);return runApp(app);});
}
复制代码

2.4.组件的再封装

你会发现上面虽然能用,但是看着真的非常难受,怎么让它用起来爽一点呢,两个字封装
实现一个GithubUserPanel,用法是传入一个用户名参数就行了。并且复用以前的面板。
由于网络访问是异步的,我们需要一个有状态的组件,当异步加载完成之后,再setState重新渲染。

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as client;
import 'github_panel.dart';
import 'user.dart';
class GithubUserPanel extends StatefulWidget {GithubUserPanel({Key key,this.userName,}) : super(key: key);final String userName;@override_GithubUserPanelState createState() => _GithubUserPanelState();
}
class _GithubUserPanelState extends State<GithubUserPanel> {var baseUrl = "https://api.github.com/";var operate = "users/";var panel;@overridevoid initState() {super.initState();var api = baseUrl + operate + widget.userName; //urlclient.get(api).then((rep) {var user = User.fromJson(json.decode(rep.body));panel = GithubPanel(user: user,);setState(() {});});}@overrideWidget build(BuildContext context) {return Container(child: panel,);}
}
复制代码

也就这写代码就行了,是不是感受到了GithubPanel复用的爽感。


2.5.使用

这样用起来就和往常一样,只要传个名字就行了

void main() {var scaffold = Scaffold(appBar: AppBar(title: Text("Flutter之旅"),),body: GithubUserPanel(userName: "toly1994328",));var app = MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: scaffold,);return runApp(app);}
复制代码

3.网络请求包dio的使用

dio作为JoJo的奇妙冒险的几部大boss,听名字就挺霸气,在网页搜dio根本没有Flutter的事
上来说的那个http包相对比较原始,dio封装的更好些,用法比较多。
反正再怎么玩,都脱离不了http请求,所以要分清主次,切莫舍本逐末。

dependencies:dio: ^2.1.13
复制代码

3.1:get获取github用户信息
var dio=Dio();
var baseUrl = "https://api.github.com/";
var operate = "users/";
var api=baseUrl+operate+"toly1994328";
dio.get(api).then((rep)=>print(rep.data));
复制代码

3.2: put请求添加github项目文件
void put() {var baseUrl="https://api.github.com/";var operate="repos/toly-flutter/flutter_journey/contents/";var path="http-put-file-dio.txt";var params="?access_token=4514388836f6da9f6c6cf7ba0721f2a6d1e89528";//请求参数var api =baseUrl+operate+path+params;//urlMap<String ,String> headers = {"Content-Type":"application/json"};//请求头var reqBody="""{"message": "commit from commit from toly","content": "aGVsbG8="}""";//请求体Dio().put(api,queryParameters:headers,data: reqBody).then((rep){print(rep.statusCode);print(rep.data);});
}
复制代码

3.3:delete请求删除github项目文件

dio中的delete是可以添加请求体的

void delete() {var baseUrl="https://api.github.com/";var operate="repos/toly-flutter/flutter_journey/contents/";var path="http-put-file-dio.txt";var params="?access_token=4514388836f6da9f6c6cf7ba0721f2a6d1e89528";//请求参数var api =baseUrl+operate+path+params;//urlMap<String ,String> headers = {"Content-Type":"application/json"};var reqBody="""{"message": "delete by toly","sha": "b6fc4c620b67d95f953a5c1c1230aaab5db5a1b0"}""";Dio().delete(api,queryParameters:headers,data: reqBody).then((rep){print(rep.data);});
}
复制代码

3.4:post提交一条issue
void post() {var baseUrl="https://api.github.com/";var operate="repos/toly-flutter/flutter_journey/issues";var params="?access_token=4514388836f6da9f6c6cf7ba0721f2a6d1e89528";//请求参数var api =baseUrl+operate+params;//urlMap<String ,String> headers = {"Content-Type":"application/json"};//请求头var reqBody="""
{"title": "张风捷特烈","body": "我是谁,我在哪里,我要到哪去?"
}""";//请求体Dio().post(api,queryParameters:headers,data: reqBody).then((rep){print(rep.statusCode);print(rep.data);});
}
复制代码

3.5:通过dio下载

就拿掘金的app下载吧,在dio中是很方便的,一行搞定。

var url="https://landing.juejin.im/app-download?utm_source=app_download&utm_medium=yingyongbao&utm_campaign=app1808";
Dio().download(url,"./掘金.apk").then((rep){print(rep.statusCode);print(rep.data);
});
复制代码

3.6:通过dio上传

文件上传一直是个较难问题,要实现文件上传,你需要一点后端的知识
核心就是客户端将数据通过请求给服务器,服务器将请求中的内容进行操作
上传也就是服务器将数据或文件存储到了服务端指定位置。
一般通过表单提交,也可以直接将二进制流通过请求体给服务端。

FormData formData = FormData.from({//创建表单"name": "toly","age": 25,"data":  UploadFileInfo(File("./data.json"), "data.json"),"image":  UploadFileInfo(File("./photo.png"), "photo.png"),
});
var api="/loadFile";
Dio().post(api, data: formData).then((rep){//将表单通过请求体传给服务端
});
复制代码

3.7:基本配置参数

看Dio的源码中有一个可选参数BaseOptions

---->[dio-2.1.13/lib/src/dio.dart:53]----
class Dio {/// Create Dio instance with default [Options]./// It's mostly just one Dio instance in your application.Dio([BaseOptions options]) {---->[dio-2.1.13/lib/src/options.dart:39]----
class BaseOptions extends _RequestConfig {BaseOptions({String method,//请求方法int connectTimeout,//链接超时int receiveTimeout,//接收超时Iterable<Cookie> cookies,//cookiesthis.baseUrl,//基础Urlthis.queryParameters,//请求参数Map<String, dynamic> extra,Map<String, dynamic> headers,//请求头ResponseType responseType = ResponseType.json,//返回类型ContentType contentType,//内容类型ValidateStatus validateStatus,bool receiveDataWhenStatusError = true,bool followRedirects = true,int maxRedirects = 5,RequestEncoder requestEncoder,ResponseDecoder responseDecoder,}) : super(
复制代码

关于更多dio的用法,这里不过多介绍,可以去这里看一下,dio作者的讲解


结语

本文到此接近尾声了,如果想快速尝鲜Flutter,《Flutter七日》会是你的必备佳品;如果想细细探究它,那就跟随我的脚步,完成一次Flutter之旅。
另外本人有一个Flutter微信交流群,欢迎小伙伴加入,共同探讨Flutter的问题,本人微信号:zdl1994328,期待与你的交流与切磋。

[- Flutter基础篇 -] 网络访问相关推荐

  1. Flutter基础篇(2)-- 老司机用一篇博客带你快速熟悉Dart语法

    版权声明:本文为博主原创文章,未经博主允许不得转载.https://www.jianshu.com/p/3d927a7bf020 转载请标明出处: https://www.jianshu.com/p/ ...

  2. java基础篇---网络编程(IP与URL)

    一:IP与InetAddress 在Java中支持网络通讯程序的开发,主要提供了两种通讯协议:TCP协议,UDP协议 可靠地连接传输,使用三方握手的方式完成通讯 不可靠的连接传输,传输的时候接受方不一 ...

  3. java基础篇---网络编程(UDP程序设计)

    UDP程序设计 在TCP的索引操作都必须建立可靠地连接,这样一来肯定会浪费大量的系统性能,为了减少这种开销,在网络中又提供了另外一种传输协议---UDP,不可靠的连接,这种协议在各个聊天工具中被广泛的 ...

  4. 【JAVA基础篇】访问权限

    所谓访问权限,指的是本类的成员变量.成员方法和内部类对其他类的可见性. 四种访问权限 Java一共有四种访问权限,按照权限由大到小分别为public.protected.default和private ...

  5. 视频教程-C# For Unity系列之基础篇-Unity3D

    C# For Unity系列之基础篇 二十多年的软件开发与教学经验IT技术布道者,资深软件工程师.具备深厚编程语言经验,在国内上市企业做项目经理.研发经理,熟悉企业大型软件运作管理过程.软件架构设计理 ...

  6. java的继承和访问_Java基础篇:如何解决成员的访问和继承?

    Java基础篇:如何解决成员的访问和继承? 尽管子类包括超类的所有成员,它不能访问超类中被声明成private的成员.例如,考虑下面简单的类层次结构: /* In a class hierarchy, ...

  7. Java基础篇:如何解决成员的访问和继承?

    Java基础篇:如何解决成员的访问和继承? 尽管子类包括超类的所有成员,它不能访问超类中被声明成private的成员.例如,考虑下面简单的类层次结构: /* In a class hierarchy, ...

  8. 网络知识基础篇(网络分层和IP地址)

    目录 一.计算机网络发展历史 二.计算机基础 1.网络层次划分 1.1五层协议 1.2七层协议(OSI  Open System Interconnection) 1.3五层与七层对应关系 1.4 T ...

  9. 【网络通信】【电信运营商实战工程师】思科设备篇-网络工程师必备基础知识

    电信运营商实战工程师系列文章. 思科设备篇-网络工程师必备基础知识. 文章目录 1. 电信运营商网络设备机房 2. 认识并管理运营商网络设备 3. GNS3 安装与配置 4. IPv4地址及子网划分 ...

最新文章

  1. fourinone学习笔记一(上手demo)
  2. bootstrap17-响应式表格布局
  3. golang context 父子任务同步取消信号 协程调度 简介
  4. vs中调试中的命令行参数
  5. Part2_1 Urllib的get请求和post请求
  6. 绿色数据中心建设刻不容缓
  7. 大数据产品开发流程规范_华为内部资料流出!揭秘华为数据湖:3大特点、6个标准、入湖流程...
  8. 数据库的运维策略脚本篇(内附脚本,无私分享)
  9. html实现点赞效果,js实现点赞效果
  10. CodeSnippet.info 开源说明 和 环境搭建 (第一版)
  11. 宝石光是什么石头_捡到这些石头,都是值钱货
  12. 国科大操作系统思考题答案总结
  13. 图像列表控制(CImageList)
  14. DVWA教程(一) —— Low级别
  15. 查看Linux配置的NTP,查看linux安装ntp服务器配置
  16. 智慧园区运营服务平台方案
  17. 外卖霸王餐返利小程序开发制作功能介绍
  18. DevExpress VCL Subscription 版本:21.1.5
  19. MySQL安全分析:缓解MySQL零日漏洞
  20. 校园跑腿小程序市场需要和功能分析!

热门文章

  1. 大IPD之——学习华为让业务主管成为人力资源管理的第一责任人(十六)
  2. C语言面试题实战汇总01
  3. 机器学习——聚类——密度聚类法——DBSCAN
  4. TCP协议中的序列号
  5. 无线局域网wlan是计算机网络与,什么是无线局域网(Wireless LAN, WLAN)
  6. 【ARMA仿真】基于matlab ARMA模型卡尔曼滤波【含Matlab源码 2431期】
  7. DEAP(Database for Emotion Analysis using Physiological Signals)介绍
  8. [附源码]Python计算机毕业设计SSM教务排课管理系统(程序+LW)
  9. ADI 15款常用的运算放大器的对比学习
  10. python 分数及格优秀 良好_考试成绩优秀,良好,合格各等级多少分