📅  最后修改于: 2020-12-08 04:47:12             🧑  作者: Mango
Flutter提供了HTTP包来消耗HTTP资源。 http是一个基于Future的库,并使用await和async功能。它提供了许多高级方法,并简化了基于REST的移动应用程序的开发。
http包提供了一个高级类和http来执行Web请求。
http类提供了执行所有类型的HTTP请求的功能。
http方法接受url和通过Dart Map的其他信息(发布数据,其他标头等)。它请求服务器并以异步/等待模式收集响应。例如,下面的代码从指定的url中读取数据,并在控制台中将其打印出来。
print(await http.read('https://flutter.dev/'));
一些核心方法如下-
读取-通过GET方法请求指定的url并以Future
让-通过GET方法请求指定的URL,并返回作为未来<响应>的响应。响应是保存响应信息的类。
交-通过张贴所提供的数据请求通过POST方法指定的URL,并返回响应作为未来<响应>
放-通过PUT方法请求指定的URL,并返回响应作为未来<响应>
头-请求通过HEAD方法指定的URL,并返回响应作为未来<响应>
删除-通过DELETE方法请求指定的URL,并返回响应作为未来<响应>
http还提供了更标准的HTTP客户端类client。客户端支持持久连接。当对特定服务器发出大量请求时,它将很有用。需要使用close方法正确关闭它。否则,它类似于http类。示例代码如下-
var client = new http.Client();
try {
print(await client.get('https://flutter.dev/'));
}
finally {
client.close();
}
让我们创建一个简单的应用程序,以从Web服务器获取产品数据,然后使用ListView展示产品。
在Android studio product_rest_app中创建一个新的Flutter应用程序。
将默认的启动代码(main.dart)替换为我们的product_nav_app代码。
将资产文件夹从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服务器应用程序。请按照以下步骤安装和运行http-服务器应用程序
安装Nodejs应用程序( nodejs.org )
转到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对象,然后转换为相关对象(产品)。
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
class MyHomePage extends StatelessWidget {
final String title;
final Future> products;
MyHomePage({Key key, this.title, this.products}) : super(key: key);
...
在MyApp小部件的构建方法中更改home选项(MyHomePage)以适应上述更改-
home: MyHomePage(title: 'Product Navigation demo home page', products: products),
更改主要函数以包括Future
void main() => runApp(MyApp(fetchProduct()));
创建一个新的小部件ProductBoxList,以在主页中构建产品列表。
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小部件的build方法,以使用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 >)中获取数据。如果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而不是在编码应用程序时输入的本地静态数据外,它与我们的Navigation示例相同。