Flutter网络请求的封装示例
1. HttpUtils 类
import 'package:dio/dio.dart';
class HttpUtils {
static String TAG = "HttpUtils";
static HttpUtils? _instance = HttpUtils._internal();
static HttpUtils getInstance() {
_instance ??= HttpUtils._internal();
return _instance!;
}
late Dio mDio;
HttpUtils._internal() {
BaseOptions options = BaseOptions(
baseUrl: AppConstants.httpBaseUrl,
connectTimeout: const Duration(seconds: 30),
receiveTimeout: const Duration(seconds: 30),
contentType: 'application/json;Charset=UTF-8',
responseType: ResponseType.json);
mDio = Dio(options);
mDio.interceptors.add(CustomInterceptor());
}
Future<Response<Map<String, dynamic>?>> get(String path,
{Map<String, dynamic>? params}) {
return mDio.get<Map<String, dynamic>?>(path, queryParameters: params);
}
Future<Response<Map<String, dynamic>?>> post(String path, {dynamic data}) {
return mDio.post<Map<String, dynamic>?>(path, data: data);
}
Future<Response<Map<String, dynamic>?>> delete(String path, {dynamic data}) {
return mDio.delete<Map<String, dynamic>?>(path, data: data);
}
Future<Response<Map<String, dynamic>?>> put(String path, {dynamic data}) {
return mDio.put<Map<String, dynamic>?>(path, data: data);
}
Future<BaseResponse> request(String url,
{String method = 'get', params, UrlType urlType = UrlType.normal}) async {
Response response;
mDio.options.baseUrl = getBaseUrl(urlType);
BaseResponse resultResponse;
try {
if (method == RequestMethod.post) {
response = await post(url, data: params);
} else if (method == RequestMethod.delete) {
response = await delete(url, data: params);
} else if (method == RequestMethod.put) {
response = await put(url, data: params);
} else {
response = await get(url, params: params);
}
final dynamic responseData = response.data;
if (response.statusCode == 200) {
if (url == HttpUrlConstants.getLoginPublicKey) {
resultResponse = BaseResponse.fromMap({
"code": ResultCode.success,
"desc": responseData?["message"],
"biz": responseData,
});
} else {
resultResponse = BaseResponse.fromMap(responseData);
}
} else {
resultResponse = BaseResponse.fromMap({
"code": ResultCode.errorNetwork,
"desc": response.statusMessage,
"biz": responseData,
});
}
} on Exception catch (e) {
String errorMessage = _handlerError(e);
resultResponse = BaseResponse.fromMap({
"code": ResultCode.errorUnknown,
"desc": errorMessage,
"biz": null,
});
}
return resultResponse;
}
void exitLogin() {}
static String _handlerError(Exception e) {
if (e is DioException) {
switch (e.type) {
case DioExceptionType.connectionTimeout:
return StringRes.error_connection_timeout;
case DioExceptionType.receiveTimeout:
return "响应超时";
case DioExceptionType.sendTimeout:
return "发送超时";
case DioExceptionType.cancel:
return "请求取消";
case DioExceptionType.badResponse:
return "服务异常";
case DioExceptionType.badCertificate:
return "错误证书";
case DioExceptionType.connectionError:
return "连接错误";
default:
return "未知错误";
}
}
return "未知错误";
}
String getBaseUrl(UrlType type) {
var baseURl = AppConstants.httpBaseUrl;
switch (type) {
case UrlType.normal:
baseURl = AppConstants.httpBaseUrl;
break;
case UrlType.login:
baseURl = AppConstants.loginHttpBaseUrl;
break;
}
LogUtils.i(TAG, baseURl);
return baseURl;
}
}
2. RequestClient 类
class RequestTool {
static Future<dynamic> request(
String url, {
String method = 'get',
params,
UrlType urlType = UrlType.normal,
}) async {
return HttpUtils.getInstance()
.request(url, method: method, params: params)
.then((res) {
if (res.code == ResultCode.errorLoginInvalid) {
LoginManager.loginInvalid();
} else if (res.code != ResultCode.success) {
LogUtils.i("httpRequestError", "error:${res.toJson()}");
throw ErrorBean(
errorCode: res.code!,
errorMessage: res.desc!,
).toMap();
} else {
if(res.biz==null){
if(res.code == ResultCode.success){
return "成功";
}
}
return res.biz;
}
});
}
}
3. 拦截器的封装
import 'dart:collection';
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
class CustomInterceptor extends Interceptor {
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
options.contentType = 'application/json;Charset=UTF-8';
options.headers = configHeaderMap(options);
StringBuffer buffer = StringBuffer();
buffer.write('\n');
buffer.write('| - Url: ${options.uri}\n');
buffer.write('| - Content-Type:${options.contentType}\n');
buffer.write('| - Method:${options.method}\n');
buffer.write('| - Header:${options.headers.toString()}\n');
buffer.write('| - body:${options.data}\n');
LogUtils.i('HttpClient','onRequest:${buffer.toString()}');
return handler.next(options);
}
@override
void onResponse(Response response, ResponseInterceptorHandler handler) {
LogUtils.i('CustomInterceptor','onResponse:${response.data}');
return handler.next(response);
}
@override
void onError(DioException err, ErrorInterceptorHandler handler) {
LogUtils.e('CustomInterceptor','onError:${err.message}');
return handler.next(err);
}
Map<String, dynamic> configHeaderMap(RequestOptions options) {
Map<String, dynamic> headerMap = options.headers;
headerMap['AccessToken'] =UserInfoManager.getInstance().getAccessToken();
if (Platform.isIOS){
headerMap['X-Platform'] ="iOS" ;
}else if(Platform.isAndroid){
headerMap['X-Platform'] ="Android" ;
}else{
headerMap['X-Platform'] ="other" ;
}
LogUtils.i('CustomInterceptor', headerMap.toString());
return headerMap;
}
}
4. 具体使用
RequestClient.request("url地址").then((value) {});