Gepostet vor 2024-05-14 Aktualisiert vor 2024-05-14 3 minutes lesen (Über 446 Wörter)
Flutter网络封装 依赖库
dio: dio 是一个强大的 HTTP 网络请求库
pretty_dio_logger: 基于拦截器的简明易读的请求日志打印
json_annotation: 用于生成 JSON 序列化与反序列化代码
retrofit: 对 dio 进一步封装
目录 1 2 3 4 5 6 7 8 9 . ├── api │ └── example_api.dart ├── model │ └── base_response.dart ├── services │ └── api_service.dart └── utils └── request_helper.dart
返回数据基类base_response.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @JsonSerializable (genericArgumentFactories : true ) class BaseResponse <T> { final T? data; final int code; final String ? msg; BaseResponse ({ this .msg , this .data , required this .code , }); factory BaseResponse .fromJson ( Map <String , dynamic> json, T Function (dynamic json) fromJsonT, ) => _$BaseResponseFromJson<T>(json, fromJsonT); Map <String , dynamic> toJson (Object ? Function (T value) toJsonT) => _$BaseResponseToJson<T>(this , toJsonT); }
接口定义类example_api.dart
1 2 3 4 5 6 7 8 @RestApi () abstract class ExampleApi { factory ExampleApi (Dio dio) = _ExampleApi; @GET ("/api/resources/{path}" ) Future <BaseResponse <Data >?> fetchData (@Path () String path); }
网络请求单例api_service.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class ApiService { late Dio _dio; late ExampleApi exampleApi; factory ApiService () => _instance; static final ApiService _instance = ApiService ._internal (); ApiService ._internal (); void initialize (String baseUrl ) { _dio = Dio ( BaseOptions ( baseUrl : baseUrl, connectTimeout : const Duration (seconds : 10 ), receiveTimeout : const Duration (seconds : 10 ), headers : {"Content-Type" : "application/json" }, ), ); _dio.interceptors ..add (TokenInterceptor ()) ..add (UserAgentInterceptor ()) ..add ( PrettyDioLogger ( request : false , requestHeader : true , requestBody : false , responseBody : true , responseHeader : false , error : true , compact : true , maxWidth : 90 ), ); exampleApi = ExampleApi (_dio); } }
工具方法request_helper.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Future <Result <T?, Exception >> requestSafety<T>( Future <BaseResponse <T>?> Function () block, ) async { try { final response = await block (); if (response is BaseResponse <T>) { if (response.code ~/ 100 == 2 ) { return Success (response.data ); } else if (response.code == 401 ) { return Failure (Exception (response.msg )); } else if (response.code >= 1000 ) { return Failure (Exception (response.msg )); } } return Failure (Exception ('response is null' )); } catch (e) { return Failure (Exception (e.toString ())); } }
具体使用
添加业务实体,使用JsonSerializable
注解生成Json
序列化代码
1 2 3 4 5 6 7 8 9 10 11 12 @JsonSerializable () class Data { final String name; const Data ({ required this .name , }); factory Data .fromJson (Map <String , dynamic> json) => _$DataFromJson (json); Map <String , dynamic> toJson () => _$DataToJson (this ); }
添加业务接口,注意返回值为Future<BaseResponse<实体>?>
1 2 @POST ("/api/resources" ) Future <BaseResponse <Data >?> fetchData ();
调用接口
1 2 3 4 5 final result = await requestSafety (() => _apiService.resourcesApi .fetchData ()); final data = result.success ; if (data != null ) { debugPrint (data.name ); }
You need to set install_url
to use ShareThis. Please set it in _config.yml
.