flutter 访问 rest api——迹忆客-ag捕鱼王app官网
flutter 提供 http 包来消耗 http 资源。 http 是一个基于 future 的库,使用 await 和 async 特性。 它提供了许多高级方法并简化了基于 rest 的移动应用程序的开发。
基本概念
http 包提供了一个高级类和 http 来做 web 请求。
http 类提供了执行所有类型的 http 请求的功能。
http 方法通过 dart map 接受 url 和附加信息(发布数据、附加标头等)。 它请求服务器并以异步/等待模式收集响应。 例如,下面的代码从指定的 url 读取数据并在控制台中打印出来。
print(await http.read('https://flutter.dev/'));
一些核心方法如下 -
- read - 通过 get 方法请求指定的 url 并将响应返回为 future
- get - 通过 get 方法请求指定的 url,并将响应返回为 future
。 response 是一个保存响应信息的类。 - post - 通过发布提供的数据并通过 post 方法请求指定的 url 并将响应返回为 future
- put - 通过 put 方法请求指定的 url 并将响应返回为 future
- head - 通过 head 方法请求指定的 url 并将响应返回为 future
- delete - 通过 delete 方法请求指定的 url,并将响应返回为 future
http 还提供了一个更标准的 http 客户端类 client。客户端支持持久连接。当向特定服务器发出大量请求时,它将很有用。它需要使用 close 方法正确关闭。否则,它类似于 http 类。示例代码如下
var client = new http.client();
try {
print(await client.get('https://flutter.dev/'));
}
finally {
client.close();
}
访问产品服务 api
让我们创建一个简单的应用程序来从 web 服务器获取产品数据,然后使用 listview 显示产品。
在 android studio 中新建一个 flutter 应用程序 product_rest_app。
将默认启动代码 (main.dart) 替换为我们的 product_nav_app 代码。
将 assets 文件夹从 product_nav_app 复制到 product_rest_app 并在 pubspec.yaml 文件中添加资源。
flutter:
assets:
- assets/appimages/floppy.png
- assets/appimages/iphone.png
- assets/appimages/laptop.png
- assets/appimages/pendrive.png
- assets/appimages/pixel.png
- assets/appimages/tablet.png
在 pubspec.yaml 文件中配置 http 包,如下所示 -
dependencies:
http: ^0.12.0 2
在这里,我们将使用最新版本的 http 包。android studio 将发送一个包警报,告知 pubspec.yaml 已更新。
单击获取依赖项选项。android studio 将从 internet 获取包并为应用程序正确配置它。
在 main.dart 文件中导入 http 包 -
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
使用产品信息创建一个新的 json 文件 products.json,如下所示 -
[
{
"name": "iphone",
"description": "iphone is the stylist phone ever",
"price": 1000,
"image": "iphone.png"
},
{
"name": "pixel",
"description": "pixel is the most feature phone ever",
"price": 800,
"image": "pixel.png"
},
{
"name": "laptop",
"description": "laptop is most productive development tool",
"price": 2000,
"image": "laptop.png"
},
{
"name": "tablet",
"description": "tablet is the most useful device ever for meeting",
"price": 1500,
"image": "tablet.png"
},
{
"name": "pendrive",
"description": "pendrive is useful storage medium",
"price": 100,
"image": "pendrive.png"
},
{
"name": "floppy drive",
"description": "floppy drive is useful rescue storage medium",
"price": 20,
"image": "floppy.png"
}
]
创建一个新文件夹 jsonwebserver 并放置 json 文件 products.json。
以 jsonwebserver 作为其根目录运行任何 web 服务器并获取其 web 路径。例如,http://192.168.184.1:8000/products.json
。我们可以使用任何 web 服务器,如 apache、nginx 等,
最简单的方法是安装基于节点的 http-server 应用程序。按照下面给出的步骤安装和运行 http-server 应用程序
- 安装 nodejs 应用程序
- 转到 jsonwebserver 文件夹。
cd /path/to/jsonwebserver
使用 npm 安装 http-server 包。
$ npm install -g http-server
现在,运行服务器。
$ http-server . -p 8000
starting up http-server, serving .
available on:
http://192.168.99.1:8000
http://127.0.0.1:8000
hit ctrl-c to stop the server
在 lib 文件夹中创建一个新文件 product.dart 并将 product 类移动到其中。
在 product 类中编写一个工厂构造函数 product.frommap 将映射的数据 map 转换为 product 对象。通常情况下,json 文件会先转换为 dart map 对象,然后再转换为相关对象(product)。
factory product.fromjson(map data) {
return product(
data['name'],
data['description'],
data['price'],
data['image'],
);
}
product.dart 的完整代码如下 -
class product {
final string name;
final string description;
final int price;
final string image;
product(this.name, this.description, this.price, this.image);
factory product.frommap(map json) {
return product(
json['name'],
json['description'],
json['price'],
json['image'],
);
}
}
在主类中编写两个方法 - parseproducts
和 fetchproducts
- 以从 web 服务器获取产品信息并将其加载到 list
对象中。
list parseproducts(string responsebody) {
final parsed = json.decode(responsebody).cast
请注意以下几点 -
- future 用于延迟加载产品信息。延迟加载是一个将代码执行推迟到必要时执行的概念。
- http.get 用于从 internet 获取数据。
- json.decode 用于将 json 数据解码为 dart map 对象。解码 json 数据后,将使用 product 类的 frommap 将其转换为 list
。
在 myapp 类中,添加新成员变量,future
class myapp extends statelesswidget {
final future> products;
myapp({key key, this.products}) : super(key: key);
...
在 myhomepage 类中,添加 future
类型的新成员变量 products 并将其包含在构造函数中。此外,删除 items 变量及其相关方法,getproducts 方法调用。将 products 变量放在构造函数中。它只允许在应用程序首次启动时从 internet 获取产品一次。
class myhomepage extends statelesswidget {
final string title;
final future> products;
myhomepage({key key, this.title, this.products}) : super(key: key);
...
在 myapp 小部件的构建方法中更改ag捕鱼王app官网主页选项(myhomepage)以适应上述更改 -
home: myhomepage(title: 'product navigation demo home page', products: products),
更改主函数以包含 future
参数
void main() => runapp(myapp(fetchproduct()));
创建一个新的小部件 productboxlist 以在ag捕鱼王app官网主页中构建产品列表。
class productboxlist extends statelesswidget {
final list items;
productboxlist({key key, this.items});
@override
widget build(buildcontext context) {
return listview.builder(
itemcount: items.length,
itembuilder: (context, index) {
return gesturedetector(
child: productbox(item: items[index]),
ontap: () {
navigator.push(
context, materialpageroute(
builder: (context) =gt; productpage(item: items[index]),
),
);
},
);
},
);
}
}
请注意,我们使用导航应用程序中使用的相同概念来列出产品,只是它通过传递 list
类型的产品(对象)设计为单独的小部件。
最后,修改myhomepage小部件的构建方法,以使用 future 选项而不是普通的方法调用来获取产品信息。
widget build(buildcontext context) {
return scaffold(
appbar: appbar(title: text("product navigation")),
body: center(
child: futurebuilder>(
future: products, builder: (context, snapshot) {
if (snapshot.haserror) print(snapshot.error);
return snapshot.hasdata ? productboxlist(items: snapshot.data)
// return the listview widget :
center(child: circularprogressindicator());
},
),
)
);
}
这里请注意,我们使用 futurebuilder 小部件来呈现小部件。futurebuilder 将尝试从它的未来属性(future> 类型)中获取数据。如果 future 属性返回数据,它将使用 productboxlist 呈现小部件,否则抛出错误。
main.dart 的完整代码如下 -
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'product.dart';
void main() => runapp(myapp(products: fetchproducts()));
list parseproducts(string responsebody) {
final parsed = json.decode(responsebody).cast
最后运行应用程序以查看结果。它将与我们的导航示例相同,只是数据来自 internet,而不是在编写应用程序时输入的本地静态数据。