Flutter网络请求插件dio_http_client的使用
Flutter网络请求插件dio_http_client的使用
dio_http_client
是一个高级封装库,用于处理网络请求。它目前支持认证令牌和缓存系统(通过 dio_http_cache
)。
添加依赖
为了使 dio_http_client
能正常工作,你还需要添加以下依赖:
dependencies:
dio: ^4.0.x #最新版本
dio_http_client: ^0.0.x #最新版本
dio_http_cache: ^0.3.x #最新版本
dartz: ^0.10.x #最新版本
数据结构
我们建议使用如下的数据结构:
data/
|-request/
|-response/
|-name_repository_impl.dart
|-name_repository.dart
在 request
目录下,每个请求都有一个对应的类。
在 response
目录下,每个响应都有一个对应的类。
简单示例
TestGetRequest
class TestGetRequest extends ApiRequest {
TestGetRequest()
: super(
baseUrl: Constants.domain, //您的域名
endPoint: "${Constants.getEndpoint}?key=value", //您的端点
method: RestMethod.get, //请求方法
decoder: (data) =>
TestGetResponse.fromMap(Map<String, dynamic>.from(data))); //响应解码器
}
TestGetResponse
class TestGetResponse extends ApiResponse<Map<String, dynamic>> {
TestGetResponse._( //私有构造函数
{Map<String, dynamic>? body, String? message, String? result}) //body的类型为你需要的类型,也需要在仓库中设置
: super(body: body, message: message, result: result);
factory TestGetResponse.fromMap(Map<String, dynamic> data) {
return TestGetResponse._(body: data["args"]);
}
}
TestRepository
abstract class TestRepository extends RemoteRepository {
TestRepository(AppHttpClient remoteDataSource) : super(remoteDataSource);
Future<Either<ErrorResponse, SuccessResponse<Map<String, dynamic>>>> testGet( //更改SuccessResponse的类型为你需要的类型
{bool? cached, bool? forceRefresh}); //如果需要缓存响应,则将cached设置为true;如果需要刷新缓存响应,则将forceRefresh设置为true;如果不希望缓存,则留空
}
TestRepositoryImpl
class TestRepositoryImpl extends TestRepository {
TestRepositoryImpl(AppHttpClient remoteDataSource) : super(remoteDataSource);
[@override](/user/override)
Future<Either<ErrorResponse, SuccessResponse<Map<String, dynamic>>>> testGet(
{bool? cached, bool? forceRefresh}) async {
final response = await dataSource.retrieveData<TestGetResponse>( //设置返回类型
TestGetRequest(),
cached: cached,
forceRefresh: forceRefresh,
);
return response.fold(
(error) => Left(error),
(success) => Right(
SuccessResponse(success.statusCode, success.data.body ?? {})));
}
}
拦截器
LoggingInterceptor
这是为了在控制台中记录所有请求和响应。
你可以创建自己的拦截器并将其附加到客户端。
快速开始
- 初始化客户端:
AppHttpClient client = AppHttpClient(debug: true, interceptors: [ //添加所有需要的拦截器
LoggingInterceptor(),
DioCacheManager(CacheConfig(baseUrl: "https://www.google.it")).interceptor //如果需要缓存你的应用,则添加此拦截器
],
requestReceiveTimeout: 3600, //全局接收超时
requestSendTimeout: 3600, //全局发送超时
);
- 初始化仓库:
TestRepository testRepository = TestRepositoryImpl(client);
- 发起请求:
final response = await testRepository.testGet();
更新授权令牌
要更新授权令牌,可以调用:
client.updateToken(token);
我们建议使用 get_it
作为依赖注入来管理你的实例。
请求类
当你创建请求类时,需要扩展 ApiRequest
。
只在需要时覆盖方法:
class TestGetRequest extends ApiRequest {
TestGetRequest()
: super(
token: //授权令牌,
userEmail: //用户邮箱,
baseUrl: //您的域名,
endPoint: //您的端点,
method: //请求方法 (RestMethod.get, post, patch, put, delete),
decoder: (data) => //响应解码器,
);
[@override](/user/override)
//请求体
Map<String, dynamic> get body => super.body;
[@override](/user/override)
//查询参数
Map<String, dynamic> get queryParameters => super.queryParameters;
[@override](/user/override)
// Dio 响应类型。默认为 ResponseType.json
ResponseType get responseType => super.responseType;
[@override](/user/override)
//默认为36000毫秒
int get receiveTimeout => super.receiveTimeout;
[@override](/user/override)
//默认为36000毫秒
int get sendTimeout => super.sendTimeout;
}
响应类
当你创建响应类时,需要扩展 ApiResponse
。
class TestGetResponse extends ApiResponse<Map<String, dynamic>> {
TestGetResponse._({
Map<String, dynamic>? body,
String? message,
String? result,
}) : super(
body: body,
message: message,
result: result,
);
factory TestGetResponse.fromMap(Map<String, dynamic> data) { //解码器需要调用工厂方法
return TestGetResponse._(body: data["args"]);
}
}
仓库实现类
class TestRepositoryImpl extends TestRepository { //继承抽象仓库
TestRepositoryImpl(AppHttpClient remoteDataSource) : super(remoteDataSource);
[@override](/user/override)
Future<Either<ErrorResponse, SuccessResponse<Map<String, dynamic>>>> testGet(
{bool? cached, bool? forceRefresh}) async {
final response = await dataSource.retrieveData<TestGetResponse>( //设置返回类型
TestGetRequest(),
cached: cached, // 如果希望缓存响应,则设为true
forceRefresh: forceRefresh, // 如果希望刷新缓存,则设为true
duration: Duration(days: 1) // 设置缓存持续时间,默认为7天
);
// 返回正确的响应
return response.fold(
(error) => Left(error),
(success) => Right(
SuccessResponse(success.statusCode, success.data.body ?? {})));
}
}
更多关于Flutter网络请求插件dio_http_client的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter网络请求插件dio_http_client的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
dio_http_client
是 Flutter 中一个非常流行的网络请求插件,它基于 Dio
库,提供了强大的功能和灵活的配置选项。以下是使用 dio_http_client
的基本步骤和示例。
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 dio
依赖:
dependencies:
flutter:
sdk: flutter
dio: ^5.0.0 # 请检查最新版本
然后运行 flutter pub get
来安装依赖。
2. 导入库
在你的 Dart 文件中导入 dio
库:
import 'package:dio/dio.dart';
3. 创建 Dio 实例
你可以创建一个 Dio
实例来进行网络请求:
final dio = Dio();
4. 发起 GET 请求
你可以使用 dio.get
方法来发起一个 GET 请求:
void fetchData() async {
try {
var response = await dio.get('https://jsonplaceholder.typicode.com/posts/1');
print(response.data);
} catch (e) {
print('Error: $e');
}
}
5. 发起 POST 请求
你可以使用 dio.post
方法来发起一个 POST 请求:
void postData() async {
try {
var response = await dio.post(
'https://jsonplaceholder.typicode.com/posts',
data: {
'title': 'foo',
'body': 'bar',
'userId': 1,
},
);
print(response.data);
} catch (e) {
print('Error: $e');
}
}
6. 配置请求头
你可以通过 Options
来配置请求头:
void fetchDataWithHeaders() async {
try {
var response = await dio.get(
'https://jsonplaceholder.typicode.com/posts/1',
options: Options(headers: {
'Authorization': 'Bearer your_token_here',
}),
);
print(response.data);
} catch (e) {
print('Error: $e');
}
}
7. 处理响应
Dio
的响应对象包含了请求的详细信息,包括状态码、数据和响应头:
void fetchData() async {
try {
var response = await dio.get('https://jsonplaceholder.typicode.com/posts/1');
print('Status Code: ${response.statusCode}');
print('Response Data: ${response.data}');
print('Response Headers: ${response.headers}');
} catch (e) {
print('Error: $e');
}
}
8. 处理错误
你可以使用 try-catch
块来捕获和处理请求中的错误:
void fetchData() async {
try {
var response = await dio.get('https://jsonplaceholder.typicode.com/posts/1');
print(response.data);
} on DioException catch (e) {
if (e.response != null) {
print('Error Response: ${e.response}');
} else {
print('Error Message: ${e.message}');
}
}
}
9. 全局配置
你可以通过 BaseOptions
来全局配置 Dio
实例:
final dio = Dio(BaseOptions(
baseUrl: 'https://jsonplaceholder.typicode.com',
connectTimeout: Duration(seconds: 5),
receiveTimeout: Duration(seconds: 3),
headers: {
'Authorization': 'Bearer your_token_here',
},
));
10. 拦截器
Dio
提供了拦截器功能,你可以在请求和响应之间添加自定义逻辑:
dio.interceptors.add(InterceptorsWrapper(
onRequest: (options, handler) {
// 在请求发出之前做一些事情
print('Request URL: ${options.uri}');
return handler.next(options);
},
onResponse: (response, handler) {
// 在收到响应之前做一些事情
print('Response Data: ${response.data}');
return handler.next(response);
},
onError: (DioException e, handler) {
// 在请求失败之前做一些事情
print('Error: $e');
return handler.next(e);
},
));
11. 文件上传
你可以使用 dio
来上传文件:
void uploadFile() async {
var formData = FormData.fromMap({
'file': await MultipartFile.fromFile('path/to/file.txt', filename: 'upload.txt'),
});
try {
var response = await dio.post(
'https://example.com/upload',
data: formData,
);
print(response.data);
} catch (e) {
print('Error: $e');
}
}
12. 文件下载
你可以使用 dio
来下载文件:
void downloadFile() async {
try {
var response = await dio.download(
'https://example.com/file.txt',
'path/to/save/file.txt',
);
print(response.data);
} catch (e) {
print('Error: $e');
}
}