Basic usage can be done in two ways

Callback usage
NetUtil.instance.fetchUser(UserSettingService.appMenu, successCallback: (res) {
  Log.i("resPayData === $res");
  var result = AppMenuResponse.fromJson(res);
}, errorTypeCallback: (value) {
  Log.i("resPayData === $value");
});
Copy the code
Synchronous use mode
var resPayCode =
    await NetUtil.instance.fetchUser(UserSettingService.payCode);
Log.i("resPayData === $resPayCode");
var payCodeResponse = PayCodeResponse.fromJson(resPayCode);
_updateUi(payCodeResponse);
Copy the code

Code implementation

import 'dart:convert';
import 'dart:io';

import 'package:bilibili_flutter/common/constant/bl_constant.dart';
import 'package:bilibili_flutter/common/log/bl_log.dart';
import 'package:dio/adapter.dart';
import 'package:dio/dio.dart';

import 'dart:convert' as convert;

typedef ErrorTypeCallback = void Function(a);typedef SuccessCallback = void Function(dynamic);

class NetUtil {
  NetUtil._private();

  factory NetUtil() {
    return_instance ?? = NetUtil._private(); }static NetUtil? _instance;

  staticNetUtil _getInstance() { _instance ?? = NetUtil._private();return_instance! ; }static get instance => _getInstance();

  getCurrentTimeMillis() {
    return DateTime.now().millisecondsSinceEpoch;
  }

  final _dio = Dio(BaseOptions(
    connectTimeout: 5000,
    receiveTimeout: 5000)); Future<dynamic> fetchUser(
    String path, {
    Map<String.dynamic> paramData = const <String.dynamic>{},
    SuccessCallback? successCallback,
    ErrorTypeCallback? errorTypeCallback,
  }) async {
    return await fetchData("${GlobalConstant.host}$path",
        param: paramData,
        successCallback: successCallback,
        errorTypeCallback: errorTypeCallback);
  }

  Future<dynamic> fetchData(
    String url, {
    Map<String.dynamic> param = const <String.dynamic>{},
    SuccessCallback? successCallback,
    ErrorTypeCallback? errorTypeCallback,
  }) async {
    try {
      (_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
          (client) {
        client.badCertificateCallback = (cert, host, port) {
          Log.i("host === $host");
          Log.i("port === $port");
          Log.i("sha1 === ${cert.sha1}");
          Log.i("issuer === ${cert.issuer}");
          Log.i("pem === ${cert.pem}");
          return true;
        };
      };
      Log.i("Was called once.");
      Log.i("url == $url");
      var jsonParam = <String.dynamic> {}; param.forEach((key, value) { jsonParam[key] = value; }); jsonParam["ts"] = getCurrentTimeMillis();

      _dio.interceptors.add(InterceptorsWrapper(onRequest: (options, handler) {
        _dio.lock();
        options.headers.remove("Content-Type");
        var headerParam = {
          "Connection": "true"."os": _getPlatformName(),
          "lang": "zh-cn"."ENCRYPT": "1"."Content-Type": "application/x-www-form-urlencoded"
        };
        // headerParam["token"] = token;
        options.headers.addAll(headerParam);
        _dio.unlock();
        // Request data before interception
        handler.next(options);
      }, onResponse: (response, handler) {
        // Respond to data interception
        Log.i("onResponse:x === $response  y ==== $handler");
        handler.next(response); // Make sure the link is associated, otherwise the request will not be invoked.
      }, onError: (error, handler) {
        // Abnormal data interception
        Log.i("onError:x === $error  y ==== $handler");
        handler.next(error);
      }));
      var requestParam = convert.jsonEncode(jsonParam);

      Log.i("Request parameters are not encrypted:$requestParam");
      // var encodeParam = aesEncode(requestParam, encryptKey, aesIv);

      // log. I (" Request parameters are encrypted :$encodeParam");
      // var response =
      // await _dio.post
      
       (url, data: "post_data=$encodeParam");
      
      var response = await _dio.post<String>(url, data: "post_data=");

      if (response.statusCode == 200) {
        Log.i("response statusCode ==  ${response.statusCode}");
        Log.i("response data ==  ${response.data}");
        var resContent =response.data ?? "";
            ""; //aesDecode(response.data ?? "", encryptKey, aesIv);
        varresValue = json.decode(resContent); successCallback? .call(resValue);// log. I (" Decrypt data :$resContent");
        return resValue;
      } else {
        //TODO prompts other exceptions
        errorTypeCallback?.call();
      }
    } catch (e) {
      Log.i("Error === was sent$e");
      errorTypeCallback?.call();
    }
  }

  /**
   Define a private type of fetching platform */
  String _getPlatformName() {
    if (Platform.isAndroid) {
      return "Android";
    } else if (Platform.isIOS) {
      return "ios";
    } else {
      return "OtherOS"; }}}Copy the code

Matters needing attention

1. After adding interceptors, the chain needs to be manually called, presumably using the responsibility chain pattern in design mode.

_dio.interceptors.add(InterceptorsWrapper(onRequest: (options, handler) {
  _dio.lock();
  options.headers.remove("Content-Type");
  var headerParam = {
    "Connection": "true".// "csrf": csrf,
    "os": _getPlatformName(),
    "lang": "zh-cn"."ENCRYPT": "1"."Content-Type": "application/x-www-form-urlencoded"
  };
  // headerParam["token"] = token;
  options.headers.addAll(headerParam);
  _dio.unlock();///I need a lock here.
  // Request data before interception
  handler.next(options);///You need to call next manually here, or the other registered events in the event flow will not execute.
}, onResponse: (response, handler) {
  // Respond to data interception
  Log.i("onResponse:x === $response  y ==== $handler");
  handler.next(response); // Make sure the link is associated, otherwise the request will not be invoked.
}, onError: (error, handler) {
  // Abnormal data interception
  Log.i("onError:x === $error  y ==== $handler");
  handler.next(error);///You need to call next manually here, or the other registered events in the event flow will not execute.
}));

Copy the code
2. Verify the HTTPS certificate
(_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
    (client) {
  client.badCertificateCallback = (cert, host, port) {
    Log.i("host === $host");
    Log.i("port === $port");
    Log.i("sha1 === ${cert.sha1}");
    Log.i("issuer === ${cert.issuer}");
    Log.i("pem === ${cert.pem}");
    return true;///If false is used here, the request will be terminated.
  };
};
Copy the code

The source address

Github.com/HaiYangCode…