Flutter Dio 网络请求详解企业级 HTTP 客户端引言在 Flutter 开发中网络请求是不可或缺的一部分。Dio 是一个强大的 HTTP 客户端库支持拦截器、全局配置、FormData、文件上传下载等功能是 Flutter 社区最受欢迎的网络请求库之一。Dio 基础用法安装依赖dependencies: dio: ^5.0.0创建 Dio 实例import package:dio/dio.dart; final dio Dio();基本 GET 请求void fetchData() async { try { final response await dio.get(https://api.example.com/data); print(response.data); } catch (e) { print(Error: $e); } }基本 POST 请求void postData() async { try { final response await dio.post( https://api.example.com/data, data: { name: John, age: 30, }, ); print(response.data); } catch (e) { print(Error: $e); } }高级配置全局配置final dio Dio(BaseOptions( baseUrl: https://api.example.com, connectTimeout: const Duration(seconds: 5), receiveTimeout: const Duration(seconds: 3), headers: { Content-Type: application/json, Authorization: Bearer token, }, ));请求配置final response await dio.get( /users, queryParameters: {page: 1, limit: 10}, options: Options( method: GET, headers: {Custom-Header: value}, responseType: ResponseType.json, ), );拦截器请求拦截器dio.interceptors.add(InterceptorsWrapper( onRequest: (options, handler) { print(Request: ${options.method} ${options.path}); options.headers[Authorization] Bearer token; return handler.next(options); }, ));响应拦截器dio.interceptors.add(InterceptorsWrapper( onResponse: (response, handler) { print(Response: ${response.statusCode}); return handler.next(response); }, ));错误拦截器dio.interceptors.add(InterceptorsWrapper( onError: (DioException e, handler) { print(Error: ${e.response?.statusCode}); return handler.next(e); }, ));重试拦截器dio.interceptors.add(RetryInterceptor( dio: dio, retries: 3, retryDelay: const Duration(seconds: 1), ));文件上传与下载文件上传void uploadFile() async { final formData FormData.fromMap({ file: await MultipartFile.fromFile( /path/to/file.jpg, filename: photo.jpg, ), description: A beautiful photo, }); try { final response await dio.post( /upload, data: formData, onSendProgress: (sent, total) { print(Progress: ${(sent / total * 100).toStringAsFixed(0)}%); }, ); print(response.data); } catch (e) { print(Error: $e); } }文件下载void downloadFile() async { try { final response await dio.download( https://example.com/file.pdf, /path/to/save/file.pdf, onReceiveProgress: (received, total) { print(Progress: ${(received / total * 100).toStringAsFixed(0)}%); }, ); print(Download completed); } catch (e) { print(Error: $e); } }取消请求CancelToken cancelToken CancelToken(); void fetchData() async { try { final response await dio.get( /data, cancelToken: cancelToken, ); print(response.data); } catch (e) { if (e is DioException e.type DioExceptionType.cancel) { print(Request cancelled); } } } // 取消请求 cancelToken.cancel(Request cancelled by user);封装最佳实践创建 API 服务类class ApiService { late Dio _dio; ApiService() { _dio Dio(BaseOptions( baseUrl: https://api.example.com, connectTimeout: const Duration(seconds: 5), receiveTimeout: const Duration(seconds: 3), )); _dio.interceptors.add(InterceptorsWrapper( onRequest: (options, handler) { options.headers[Authorization] Bearer ${getToken()}; return handler.next(options); }, onError: (e, handler) { if (e.response?.statusCode 401) { // 处理未授权 refreshToken(); } return handler.next(e); }, )); } FutureResponse get(String path, {MapString, dynamic? queryParameters}) { return _dio.get(path, queryParameters: queryParameters); } FutureResponse post(String path, {dynamic data}) { return _dio.post(path, data: data); } FutureResponse put(String path, {dynamic data}) { return _dio.put(path, data: data); } FutureResponse delete(String path) { return _dio.delete(path); } }模型转换class User { final String id; final String name; final String email; User({required this.id, required this.name, required this.email}); factory User.fromJson(MapString, dynamic json) { return User( id: json[id], name: json[name], email: json[email], ); } MapString, dynamic toJson() { return { id: id, name: name, email: email, }; } } class UserRepository { final ApiService apiService; UserRepository(this.apiService); FutureUser getUser(String id) async { final response await apiService.get(/users/$id); return User.fromJson(response.data); } FutureListUser getUsers() async { final response await apiService.get(/users); return (response.data as List).map((json) User.fromJson(json)).toList(); } }错误处理统一错误处理class ApiException implements Exception { final String message; final int? statusCode; ApiException({required this.message, this.statusCode}); } FutureT safeApiCallT(FutureResponse Function() apiCall) async { try { final response await apiCall(); return response.data as T; } on DioException catch (e) { throw ApiException( message: e.message ?? Unknown error, statusCode: e.response?.statusCode, ); } }测试支持Mock 请求void main() { late Dio dio; late ApiService apiService; setUp(() { dio Dio(BaseOptions(baseUrl: https://api.example.com)); apiService ApiService(); }); test(get user, () async { final user await apiService.getUser(1); expect(user.id, 1); }); }性能优化请求缓存dio.interceptors.add(CacheInterceptor());连接池final dio Dio(BaseOptions( baseUrl: https://api.example.com, connectTimeout: const Duration(seconds: 5), )); dio.httpClientAdapter HttpClientAdapter( ConnectionManager( idleTimeout: const Duration(seconds: 30), maxConnections: 10, ), );总结Dio 是一个功能强大的 HTTP 客户端库提供了丰富的功能和良好的扩展性。通过合理使用拦截器、封装 API 服务和错误处理我们可以构建健壮的网络请求层。掌握 Dio 后你可以轻松发起各种 HTTP 请求实现请求拦截和响应处理上传和下载文件取消请求构建可测试的网络层Dio 是 Flutter 网络请求的首选方案值得深入学习和使用。
Flutter Dio 网络请求详解:企业级 HTTP 客户端
Flutter Dio 网络请求详解企业级 HTTP 客户端引言在 Flutter 开发中网络请求是不可或缺的一部分。Dio 是一个强大的 HTTP 客户端库支持拦截器、全局配置、FormData、文件上传下载等功能是 Flutter 社区最受欢迎的网络请求库之一。Dio 基础用法安装依赖dependencies: dio: ^5.0.0创建 Dio 实例import package:dio/dio.dart; final dio Dio();基本 GET 请求void fetchData() async { try { final response await dio.get(https://api.example.com/data); print(response.data); } catch (e) { print(Error: $e); } }基本 POST 请求void postData() async { try { final response await dio.post( https://api.example.com/data, data: { name: John, age: 30, }, ); print(response.data); } catch (e) { print(Error: $e); } }高级配置全局配置final dio Dio(BaseOptions( baseUrl: https://api.example.com, connectTimeout: const Duration(seconds: 5), receiveTimeout: const Duration(seconds: 3), headers: { Content-Type: application/json, Authorization: Bearer token, }, ));请求配置final response await dio.get( /users, queryParameters: {page: 1, limit: 10}, options: Options( method: GET, headers: {Custom-Header: value}, responseType: ResponseType.json, ), );拦截器请求拦截器dio.interceptors.add(InterceptorsWrapper( onRequest: (options, handler) { print(Request: ${options.method} ${options.path}); options.headers[Authorization] Bearer token; return handler.next(options); }, ));响应拦截器dio.interceptors.add(InterceptorsWrapper( onResponse: (response, handler) { print(Response: ${response.statusCode}); return handler.next(response); }, ));错误拦截器dio.interceptors.add(InterceptorsWrapper( onError: (DioException e, handler) { print(Error: ${e.response?.statusCode}); return handler.next(e); }, ));重试拦截器dio.interceptors.add(RetryInterceptor( dio: dio, retries: 3, retryDelay: const Duration(seconds: 1), ));文件上传与下载文件上传void uploadFile() async { final formData FormData.fromMap({ file: await MultipartFile.fromFile( /path/to/file.jpg, filename: photo.jpg, ), description: A beautiful photo, }); try { final response await dio.post( /upload, data: formData, onSendProgress: (sent, total) { print(Progress: ${(sent / total * 100).toStringAsFixed(0)}%); }, ); print(response.data); } catch (e) { print(Error: $e); } }文件下载void downloadFile() async { try { final response await dio.download( https://example.com/file.pdf, /path/to/save/file.pdf, onReceiveProgress: (received, total) { print(Progress: ${(received / total * 100).toStringAsFixed(0)}%); }, ); print(Download completed); } catch (e) { print(Error: $e); } }取消请求CancelToken cancelToken CancelToken(); void fetchData() async { try { final response await dio.get( /data, cancelToken: cancelToken, ); print(response.data); } catch (e) { if (e is DioException e.type DioExceptionType.cancel) { print(Request cancelled); } } } // 取消请求 cancelToken.cancel(Request cancelled by user);封装最佳实践创建 API 服务类class ApiService { late Dio _dio; ApiService() { _dio Dio(BaseOptions( baseUrl: https://api.example.com, connectTimeout: const Duration(seconds: 5), receiveTimeout: const Duration(seconds: 3), )); _dio.interceptors.add(InterceptorsWrapper( onRequest: (options, handler) { options.headers[Authorization] Bearer ${getToken()}; return handler.next(options); }, onError: (e, handler) { if (e.response?.statusCode 401) { // 处理未授权 refreshToken(); } return handler.next(e); }, )); } FutureResponse get(String path, {MapString, dynamic? queryParameters}) { return _dio.get(path, queryParameters: queryParameters); } FutureResponse post(String path, {dynamic data}) { return _dio.post(path, data: data); } FutureResponse put(String path, {dynamic data}) { return _dio.put(path, data: data); } FutureResponse delete(String path) { return _dio.delete(path); } }模型转换class User { final String id; final String name; final String email; User({required this.id, required this.name, required this.email}); factory User.fromJson(MapString, dynamic json) { return User( id: json[id], name: json[name], email: json[email], ); } MapString, dynamic toJson() { return { id: id, name: name, email: email, }; } } class UserRepository { final ApiService apiService; UserRepository(this.apiService); FutureUser getUser(String id) async { final response await apiService.get(/users/$id); return User.fromJson(response.data); } FutureListUser getUsers() async { final response await apiService.get(/users); return (response.data as List).map((json) User.fromJson(json)).toList(); } }错误处理统一错误处理class ApiException implements Exception { final String message; final int? statusCode; ApiException({required this.message, this.statusCode}); } FutureT safeApiCallT(FutureResponse Function() apiCall) async { try { final response await apiCall(); return response.data as T; } on DioException catch (e) { throw ApiException( message: e.message ?? Unknown error, statusCode: e.response?.statusCode, ); } }测试支持Mock 请求void main() { late Dio dio; late ApiService apiService; setUp(() { dio Dio(BaseOptions(baseUrl: https://api.example.com)); apiService ApiService(); }); test(get user, () async { final user await apiService.getUser(1); expect(user.id, 1); }); }性能优化请求缓存dio.interceptors.add(CacheInterceptor());连接池final dio Dio(BaseOptions( baseUrl: https://api.example.com, connectTimeout: const Duration(seconds: 5), )); dio.httpClientAdapter HttpClientAdapter( ConnectionManager( idleTimeout: const Duration(seconds: 30), maxConnections: 10, ), );总结Dio 是一个功能强大的 HTTP 客户端库提供了丰富的功能和良好的扩展性。通过合理使用拦截器、封装 API 服务和错误处理我们可以构建健壮的网络请求层。掌握 Dio 后你可以轻松发起各种 HTTP 请求实现请求拦截和响应处理上传和下载文件取消请求构建可测试的网络层Dio 是 Flutter 网络请求的首选方案值得深入学习和使用。