flutter 请求封装

flutter 请求封装

使用 Dio 库

安装

flutter pub add dio

创建文件

创建配置文件

class Config {

  /// 连接超时时间
  static const int connectTimeout = 8000;

  /// 请求超时时间
  static const int requestTimeout = 8000;

  /// baseURL
  static String getBaseUrl() {

      return "xxx";
  }

  /// 请求日志输出
  static const bool logRequest = true;

  /// 默认contentType
  static const String defaultContentType = "application/json";
}

创建 HttpUtil 类

import 'dart:io';
import 'package:dio/adapter.dart';
import 'package:dio/dio.dart';
import 'package:nearhub/config/config.dart';
import 'package:nearhub/utils/device_info_util.dart';
import 'package:nearhub/utils/toast_util.dart';

/// 返回状态码
class HttpResponseCode {
  static const int successCode = 0;
  static const int errorCode = -1000;
  static const int logoutCode = 401;

  static const int connectTimeout = 6001;
  static const int receiveTimeout = 6002;
}

/// http请求方法
class HttpMethod {
  static const String get = "GET";
  static const String post = "POST";
  static const String put = "PUT";
  static const String delete = "DELETE";
  static const String option = "OPTION";
}

/// http请求contnettype
class HttpContentType {
  static const String form = "application/x-www-form-urlencoded";
  static const String formData = "multipart/form-data";
  static const String json = "application/json";
  static const String text = "text/xml";
}

/// 请求工具类
class HttpUtil {
  static proxyRequest(Dio dio, bool proxyOn, String ipString) {
    if (proxyOn) {
      (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
          (HttpClient client) {
        client.findProxy = (uri) {
          // return "PROXY 192.168.1.113:8888";
          return "PROXY $ipString:8888";
        };
        client.badCertificateCallback =
            (X509Certificate cert, String host, int port) => true;
      };
    }
  }

  /// 获取请求头
  static Future<Map<String, dynamic>> getRequestHeader({
    String contentType = Config.defaultContentType,
  }) async {
    Map<String, dynamic> headers = {};

    headers['os'] = await DeviceInfoUtil.getOs();
    headers['app_version'] = await DeviceInfoUtil.getVersion();
    headers['timestamp'] = DateTime.now().millisecondsSinceEpoch.toString();
    headers['device'] = await DeviceInfoUtil.getDeivceName();
    headers['app_store'] = DeviceInfoUtil.getChannelName();
    headers['content-type'] = contentType;
    headers['mac'] = '';

    return headers;
  }

  /// 请求成功全局处理
  static Response onSuccess(Response? res) {
    Response successResponse = res ??
        Response(
            statusCode: HttpResponseCode.errorCode,
            requestOptions: RequestOptions(path: ""));

    return successResponse;
  }

  /// 请求失败全局处理
  static Response onError(DioError error) {
    // 请求错误处理
    Response errorResponse = error.response ??
        Response(
            statusCode: HttpResponseCode.errorCode,
            requestOptions: RequestOptions(path: ""));

    switch (error.type) {
      case DioErrorType.connectTimeout: // 请求超时
        errorResponse.statusCode = HttpResponseCode.connectTimeout;
        errorResponse.statusMessage = "网络连接超时,请检查网络";
        break;
      case DioErrorType.receiveTimeout: // 请求连接超时
        errorResponse.statusCode = HttpResponseCode.receiveTimeout;
        errorResponse.statusMessage = "网络请求超时,请稍后重试";
        break;
      case DioErrorType.response: // 服务器内部错误
        errorResponse.statusCode = error.response?.statusCode;
        errorResponse.statusMessage = "服务器繁忙,请稍后重试";
        break;
      case DioErrorType.cancel: // 请求取消
        errorResponse.statusCode = error.response?.statusCode;
        errorResponse.statusMessage = "请求取消";
        break;
      case DioErrorType.other: // 其他错误
        errorResponse.statusCode = error.response?.statusCode;
        errorResponse.statusMessage = "网络错误,请稍后重试";
        break;
      default:
    }

    /// 添加错误提示
    ToastUtil.error(errorResponse.statusMessage ?? "");

    /// 返回错误
    return errorResponse;
  }
}

创建 HttpRequest 类

import 'package:dio/dio.dart';
import 'package:nearhub/api/custom_interceptor.dart';
import 'package:nearhub/config/config.dart';
import 'package:nearhub/utils/http_util.dart';
import 'package:nearhub/utils/toast_util.dart';

class HttpRequest {
  static late HttpRequest _instance;
  static bool _isInstanceCreated = false;
  static Dio? _dio;

  factory HttpRequest() => getInstance();
  static HttpRequest get instance => getInstance();
  static HttpRequest getInstance() {
    if (_isInstanceCreated == false) {
      _instance = HttpRequest._internal();
    }
    _isInstanceCreated = true;
    return _instance;
  }

  HttpRequest._internal() {
    if (_isInstanceCreated == false) {
      var options = BaseOptions(
        baseUrl: Config.getBaseUrl(),
        connectTimeout: Config.connectTimeout,
        receiveTimeout: Config.requestTimeout,
      );
      _dio = Dio(options);

      /// 加载拦截器
      _dio?.interceptors.add(CustomInterceptor());
    }
  }

  /// get请求
  Future<Response> get(
    String path, {
    Map<String, dynamic>? params,
    bool? loading = false,
    String? contentType = Config.defaultContentType,
    Function(Response res)? onSuccess,
    Function(Response errRes)? onError,
  }) async {
    return request(path, HttpMethod.get,
        params: params,
        loading: loading,
        contentType: contentType,
        onError: onError,
        onSuccess: onSuccess);
  }

  /// post请求
  Future<Response> post(
    String path, {
    Map<String, dynamic>? params,
    Map<String, dynamic>? data,
    bool? loading = false,
    String? contentType = Config.defaultContentType,
    Function(Response res)? onSuccess,
    Function(Response errRes)? onError,
  }) async {
    return request(path, HttpMethod.post,
        params: params,
        data: data,
        loading: loading,
        contentType: contentType,
        onError: onError,
        onSuccess: onSuccess);
  }

  /// put请求
  Future<Response> put(
    String path, {
    Map<String, dynamic>? params,
    Map<String, dynamic>? data,
    bool? loading = false,
    String? contentType = Config.defaultContentType,
    Function(Response res)? onSuccess,
    Function(Response errRes)? onError,
  }) async {
    return request(path, HttpMethod.put,
        params: params,
        data: data,
        loading: loading,
        contentType: contentType,
        onError: onError,
        onSuccess: onSuccess);
  }

  /// delete请求
  Future<Response> delete(
    String path, {
    Map<String, dynamic>? params,
    Map<String, dynamic>? data,
    bool? loading = false,
    String? contentType = Config.defaultContentType,
    Function(Response res)? onSuccess,
    Function(Response errRes)? onError,
  }) async {
    return request(path, HttpMethod.delete,
        params: params,
        data: data,
        loading: loading,
        contentType: contentType,
        onError: onError,
        onSuccess: onSuccess);
  }

  /// option请求
  Future<Response> option(
    String path, {
    Map<String, dynamic>? params,
    Map<String, dynamic>? data,
    bool? loading = false,
    String? contentType = Config.defaultContentType,
    Function(Response res)? onSuccess,
    Function(Response errRes)? onError,
  }) async {
    return request(path, HttpMethod.option,
        params: params,
        loading: loading,
        contentType: contentType,
        onError: onError,
        onSuccess: onSuccess);
  }

  Future<Response> request(
    String path,
    String method, {
    Map<String, dynamic>? data,
    Map<String, dynamic>? params,
    String? contentType = Config.defaultContentType,
    bool? loading = false,
    Function(Response res)? onSuccess,
    Function(Response errRes)? onError,
  }) async {
    _dio!.options.method = method;
    _dio!.options.headers['content-type'] = contentType;

    Response response = Response(
        statusCode: HttpResponseCode.errorCode,
        requestOptions: RequestOptions(path: path));

    if (loading == true) {
      ToastUtil.show();
    }

    try {
      response = await _dio?.request(
            path,
            queryParameters: params,
            data: data,
          ) ??
          response;

      onSuccess?.call(response);
    } catch (e) {
      DioError err = DioError(
        requestOptions: RequestOptions(
            path: path, method: method, queryParameters: params, data: data),
        response: response,
        type: DioErrorType.response,
      );

      if (e is DioError) {
        err.type = e.type;
      }

      response.statusCode = err.response?.statusCode;
      response.data = err.response?.data;
      response.statusMessage = err.message;

      onError?.call(response);
    }
    ToastUtil.dismiss();

    return response;
  }
}

创建 自定义拦截类

import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:nearhub/config/config.dart';
import 'package:nearhub/utils/c_log_util.dart';
import 'package:nearhub/utils/http_util.dart';

class CustomInterceptor extends Interceptor {
  @override
  void onRequest(
      RequestOptions options, RequestInterceptorHandler handler) async {
    /// 加载请求头
    Map<String, dynamic> headers = await HttpUtil.getRequestHeader();
    options.headers = headers;

    if (Config.logRequest) {
      LOG.d('');
      LOG.d('[=========== ${options.path} ==========]');
      LOG.d('[ URL    ]:${options.baseUrl + options.path}');
      LOG.d('[ METHOD ]:${options.method}');
      LOG.d('[ HEADER ]:${json.encode(options.headers)}');
      LOG.d('[ PARAMS ]:${json.encode(options.queryParameters)}');
      LOG.d('[ DATAS  ]:${json.encode(options.data)}');
    }

    handler.next(options);
  }

  @override
  void onResponse(Response response, ResponseInterceptorHandler handler) {
    /// 可以在此处处理加密

    if (Config.logRequest) {
      LOG.d('[ SUCCESS ]');
      LOG.d('[ RESULT  ]:${json.encode(response.data)}');
      LOG.d('[========================================]');
      LOG.d('');
    }

    /// 公共处理成功请求
    HttpUtil.onSuccess(response);

    handler.next(response);
  }

  @override
  void onError(DioError err, ErrorInterceptorHandler handler) {
    if (Config.logRequest) {
      LOG.d('[ *ERROR* ]');
      LOG.d('[ ERROR  ]:${json.encode(err)}');
      LOG.d('[========================================]');
      LOG.d('');
    }

    /// 公共处理失败请求
    HttpUtil.onError(err);

    handler.next(err);
  }
}

使用

Response login = await HttpRequest.instance.post("/user/login", data: {
        "username": "2185675739@qq.com",
        "password": "ywh1996",
    }, contentType: HttpContentType.form);

LOG.d(login.toString());
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值