Flutter网络请求的封装

279 阅读2分钟

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
    BaseOptions options = BaseOptions(
        baseUrl: AppConstants.httpBaseUrl,
        //连接超时
        connectTimeout: const Duration(seconds: 30),
        //接收超时
        receiveTimeout: const Duration(seconds: 30),
        //内容类型
        contentType: 'application/json;Charset=UTF-8',
        //响应数据类型:Json
        responseType: ResponseType.json);
    mDio = Dio(options);
    mDio.interceptors.add(CustomInterceptor());
  }

// 发起GET请求
  Future<Response<Map<String, dynamic>?>> get(String path,
      {Map<String, dynamic>? params}) {
    return mDio.get<Map<String, dynamic>?>(path, queryParameters: params);
  }

  // 发起POST请求
  Future<Response<Map<String, dynamic>?>> post(String path, {dynamic data}) {
    return mDio.post<Map<String, dynamic>?>(path, data: data);
  }

  // 发起delete请求
  Future<Response<Map<String, dynamic>?>> delete(String path, {dynamic data}) {
    return mDio.delete<Map<String, dynamic>?>(path, data: data);
  }

  // 发起delete请求
  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 {
        //状态不是200
        resultResponse = BaseResponse.fromMap({
          "code": ResultCode.errorNetwork,
          "desc": response.statusMessage,
          "biz": responseData,
        });
      }
    } on Exception catch (e) {
      //异常的情况
      String errorMessage = _handlerError(e);
      //状态不是200
      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 "请求取消";
        //错误响应 404 等
        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) {});