Flutter网络请求插件http_rest的使用
Flutter网络请求插件http_rest的使用
HTTP REST
HTTP REST 提供了所有必要的工具来简化和优化您的 HTTP 交互。它是一个基于流行的 Flutter 的 http 库的轻量级且灵活的网络库,并作为增强功能提供了一些额外的功能和功能,例如:
- 中间件(拦截器)
- 请求/响应体转换器
- 请求/响应日志记录
- 读/写进度跟踪
- 带有进度的多部分请求
开始使用
创建一个 HttpRestClient
实例,然后运行 HttpRestRequest
。
import 'package:http/http.dart' as http;
import 'package:http_rest/http_rest.dart';
/// ...
final httpClient = HttpRestClient.builder(DefaultRequestExecutor(http.Client()))
.addResponseConverter(JsonToMapResponseConverter()) // 添加响应转换器
.addRequestConverter(MapToJsonRequestConverter()) // 添加请求转换器
.addRequestMiddleware(RequestLogger()) // 添加请求中间件
.addResponseMiddleware(ResponseLogger()) // 添加响应中间件
.build();
// 这个请求将向图书馆添加一本书
final result = await httpClient.execute(HttpRestRequest(
method: Methods.post,
// 指定请求转换器类型
requestConverterType: MapToJsonRequestConverter,
// 指定响应转换器类型
responseConverterType: JsonToMapResponseConverter,
url: 'https://example.com/books',
headers: {'Language': 'en'},
body: {
"id": 2,
"bookName": "1984",
"author": "George Orwell"
}));
if (result.rowResponse.code == 201) {
print(result.response); // 实例为 Map
}
同样的 httpClient
实例也可以用来执行其他 HTTP 请求。
// 这个请求会获取图书馆的书籍列表。
final result = await httpClient.execute(HttpRestRequest(
method: Methods.get,
responseConverterType: JsonToMapResponseConverter,
url: 'https://example.com/books?count=10'));
中间件
HttpRestClient 使用中间件链来修改请求和响应。
以下是创建一个请求中间件以在每个 HttpRestRequest
中添加授权头的方法:
class AuthorizationMiddleware extends Middleware<RowRequest> {
@override
Future<RowRequest> onNext(
RowRequest row, Middleware<RowRequest> nextMiddleware) async {
row.request.headers['Authorization'] = 'YOUR AUTHORIZATION TOKEN';
return await super.onNext(row, nextMiddleware);
}
}
在构建 HttpRestClient
实例时添加它:
final httpClient = HttpRestClient.builder(
DefaultRequestExecutor(http.Client()))
.addResponseConverter(JsonToMapResponseConverter())
.addRequestConverter(MapToJsonRequestConverter())
.addRequestMiddleware(AuthorizationMiddleware()) // 添加
.addRequestMiddleware(RequestLogger())
.addResponseMiddleware(ResponseLogger())
.build();
因此,Authorization
头将会被添加到由 httpClient
执行的所有请求中。
请注意,RequestLogger
和 ResponseLogger
也是中间件。
可以在 HttpRestClient
中添加任意数量的请求和响应中间件,它们将以添加的顺序作为链调用。
转换器
转换器用于转换请求和响应体。库自带了一些默认的转换器:
MapToJsonRequestConverter
用于将请求的映射体转换为 JSON 字符串。JsonToMapResponseConverter
用于将响应体字节转换为映射对象。StringResponseConverter
用于将响应体字节转换为字符串。
每个 HttpRestRequest
可以指定请求和响应转换器类型,HttpRestClient
将使用指定的转换器来转换请求和响应体。
// 这个请求会获取图书馆的书籍列表。
final result = await httpClient.execute(HttpRestRequest(
method: Methods.get,
// 将请求体转换为 JSON
responseConverterType: JsonToMapResponseConverter,
url: 'https://example.com/books?count=10'));
以下是如何创建一个将接收到的体字节转换为映射实例的转换器:
import 'dart:convert';
class JsonToMapResponseConverter extends ResponseConverter {
@override
HttpRestResponse fromRow(RowResponse rowResponse) {
dynamic jsonMap;
final rowBody = rowResponse.bodyBytes;
if (rowBody != null && rowBody.isNotEmpty) {
final rowBodyUtf8 = utf8.decode(rowBody);
jsonMap = json.decode(rowBodyUtf8);
}
return HttpRestResponse(rowResponse.request, rowResponse, jsonMap);
}
}
注意,fromRow
方法接收 RowResponse
的实例并返回 HttpRestResponse
的实例。
RowResponse
是较低级别的响应模型,包含响应的bodyBytes
以及其他内容,如响应码和响应头。HttpRestResponse
是await client.execute(HttpRestRequest(...))
返回的实例,它包含原始的HttpRestRequest
、RowResponse
和转换后的体jsonMap
。
请求日志记录
RequestLogger
和 ResponseLogger
用于在控制台中记录网络交互。
这里是如何在控制台中查看记录的请求的样子:
→ REQUEST →
POST: https://example.com/books
HEADERS: Content-Type : application/json
Authorization : eyJhbGciOi....
Language : EN
Version : 1.1.76
BODY: {"id":2, "bookName":"1984", "author":"George Orwell"}
← RESPONSE ←
POST: https://example.com/books
CODE: 200
HEADERS: connection : keep-alive
date : Thu, 04 May 2023 19:02:10 GMT
transfer-encoding : chunked
vary : accept-encoding
content-encoding : gzip
strict-transport-security : max-age=15724800; includeSubDomains
content-type : application/json
BODY: {"message":"Success"}
使用 LogParts
枚举来控制可记录的部分:
enum LogParts {
headers,
body,
url,
code;
static const all = {url, headers, code, body}; // 默认
}
默认情况下,请求和响应的所有部分都会被记录。这里是仅记录 URL 和头部的方法:
final httpClient = HttpRestClient.builder(
DefaultRequestExecutor(http.Client()))
//...
.addRequestMiddleware(RequestLogger(logParts: {LogParts.url, LogParts.headers})) // 中间件
.addResponseMiddleware(ResponseLogger(logParts: {LogParts.url, LogParts.headers}))
.build();
读/写进度跟踪
要跟踪任何请求的读取/写入进度,可以使用 HttpRestRequest
的 writeProgressListener
和 readProgressListener
成员。
以下是如何从 GitHub 下载图像并跟踪下载进度的例子:
void downloadImage() =>
httpClient.execute(HttpRestRequest(
method: Methods.get,
url: 'https://raw.githubusercontent.com/RobertApikyan/http_rest/main/doc/assets/intro.png',
readProgressListener: (bytes, totalBytes) => print('download progress= ${bytes/totalBytes}'),
));
多部分请求
对于多部分请求,只需提供 MultipartRequestBody
到 HttpRestRequest
的 body
中。
以下是如何创建一个多部分请求以上传书籍并监控进度:
void uploadBook(MultipartFile multipartFile) =>
httpClient.execute(HttpRestRequest(
method: Methods.post,
url: 'https://example.com/book',
body: MultipartRequestBody(
fields: {},
files: [multipartFile],
progressListener: (bytes, totalBytes) {
// 监控进度
final progress = bytes / totalBytes;
},
),
));
请求执行器
RequestExecutor
负责实际执行 HTTP 请求并返回结果。这是一个抽象类,有一个单抽象方法 execute
。
abstract class RequestExecutor {
/// 重写此方法并使用 [rowRequest] 参数中的参数实现 HTTP 调用。
Future<RowResponse> execute(RowRequest rowRequest);
}
更多关于Flutter网络请求插件http_rest的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter网络请求插件http_rest的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter中使用http_rest
插件进行网络请求的示例代码。请注意,http_rest
可能并不是一个非常流行或者广泛认可的插件名称,通常我们会使用http
包来进行网络请求。不过,为了符合你的要求,我假设http_rest
是一个类似于http
的插件,并提供一个类似的API。
首先,确保你已经在pubspec.yaml
文件中添加了http_rest
依赖项(如果确实存在这个包的话,否则请替换为http
):
dependencies:
flutter:
sdk: flutter
http_rest: ^x.y.z # 替换为实际的版本号
然后,运行flutter pub get
来安装依赖项。
接下来,是一个使用http_rest
(假设其API类似于http
包)进行GET和POST请求的示例代码:
import 'package:flutter/material.dart';
import 'package:http_rest/http_rest.dart' as http_rest; // 假设包名为http_rest,并且有一个别名
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String _responseText = '';
void _makeGetRequest() async {
try {
var response = await http_rest.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
setState(() {
_responseText = response.body;
});
} catch (e) {
setState(() {
_responseText = 'Error: ${e.message}';
});
}
}
void _makePostRequest() async {
try {
var body = {
'title': 'foo',
'body': 'bar',
'userId': 1,
};
var response = await http_rest.post(Uri.parse('https://jsonplaceholder.typicode.com/posts'),
body: body);
setState(() {
_responseText = response.body;
});
} catch (e) {
setState(() {
_responseText = 'Error: ${e.message}';
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Network Request Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Response:', style: TextStyle(fontSize: 18)),
SizedBox(height: 10),
Expanded(
child: SingleChildScrollView(
child: Text(_responseText, style: TextStyle(fontSize: 16)),
),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _makeGetRequest,
child: Text('Make GET Request'),
),
SizedBox(height: 10),
ElevatedButton(
onPressed: _makePostRequest,
child: Text('Make POST Request'),
),
],
),
),
);
}
}
在这个示例中,我们创建了一个简单的Flutter应用,它有两个按钮,一个用于发起GET请求,另一个用于发起POST请求。GET请求从jsonplaceholder.typicode.com
获取一个帖子,而POST请求则向该网站提交一个新的帖子。
请注意,如果http_rest
实际上不存在,或者其API与http
包有很大不同,你可能需要查阅该插件的官方文档来正确调整代码。在实际开发中,http
包是Flutter社区广泛使用的网络请求插件,其API非常直观和易用。