flutter 封装dio+json泛型解析

通过例子比较了

HttpClient,http和dio,github star和功能丰富性,选择在项目中使用dio请求网络;
json_serializable+json_annotation可以作为json序列化方式,不喜欢这种方式;

我选择的在https://javiercbk.github.io/json_to_dart/把基类json生成dart class实体类,

其他类使用插件FlutterJsonBeanFactory生成dart class实体类,插件安装后记得重启IDE

pubspec.yaml 添加 dio依赖

dio: ^3.0.9

网络工具类

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

import 'package:dio/dio.dart';

class HttpManager {
  static HttpManager _instance;

  static HttpManager getInstance() {
    if (_instance == null) {
      _instance = new HttpManager();
    }
    return _instance;
  }

  HttpManager() {
    dio = createInstance();
  }

  /// global dio object
  static Dio dio;

  /// default options
  static const String _BASE_URL = "https://www.wanandroid.com/";
  static const int _CONNECT_TIMEOUT = 15000;
  static const int _RECEIVE_TIMEOUT = 15000;

  /// http request methods
  static const String GET = 'get';
  static const String POST = 'post';
  static const String PUT = 'put';
  static const String PATCH = 'patch';
  static const String DELETE = 'delete';

  get<T>(
      String url, FormData param, Function onSuccess, Function onError) async {
    requestHttp<T>(
      url,
      param: param,
      method: GET,
      onSuccess: onSuccess,
      onError: onError,
    );
  }

  post<T>(
      String url, FormData param, Function onSuccess, Function onError) async {
    requestHttp<T>(
      url,
      param: param,
      method: POST,
      onSuccess: onSuccess,
      onError: onError,
    );
  }

  /// T is Map<String,dynamic>  or List<dynamic>
  static requestHttp<T>(
    String url, {
    param,
    method,
    Function(T map) onSuccess,
    Function(String error) onError,
  }) async {
    dio = createInstance();
    try {
      Response response = await dio.request(
        url,
        data: param,
        options: new Options(method: method),
      );
      if (response.statusCode == HttpStatus.ok) {
        onSuccess(json.decode(response.data));
      } else {
        onError("【statusCode】${response.statusCode}");
      }
    } on DioError catch (e) {
      /// 打印请求失败相关信息
      print("【请求出错】${e.toString()}");
      onError(e.toString());
    }
  }

  /// 创建 dio 实例对象
  static Dio createInstance() {
    if (dio == null) {
      /// 全局属性:请求前缀、连接超时时间、响应超时时间
      var options = new BaseOptions(
        baseUrl: _BASE_URL,
        connectTimeout: _CONNECT_TIMEOUT,
        receiveTimeout: _RECEIVE_TIMEOUT,
        responseType: ResponseType.plain,
//        contentType: Headers.jsonContentType,
      );
      dio = new Dio(options);
      dio.interceptors.add(new LogInterceptors());
    }
    return dio;
  }

//  /// request method
//  static Future<Map> request<T>(
//      String url, {
//        param,
//        method,
//        Function onSuccess,
//        Function onError,
//      }) async {
    param = param ?? {};
//
//    /// restful 请求处理
//    /// /gysw/search/hist/:user_id        user_id=27
//    /// 最终生成 url 为     /gysw/search/hist/27
//    param.forEach((key, value) {
//      if (url.indexOf(key) != -1) {
//        url = url.replaceAll(':$key', value.toString());
//      }
//    });
//
//    dio = createInstance();
//    var result;
//    try {
//      Response response = await dio.request(
//        url,
//        data: param,
//        options: new Options(method: method),
//      );
//      result = json.decode(response.data);
//      if (response.statusCode == HttpStatus.ok) {
//        onSuccess(result);
//      } else {
//        onError("【statusCode】${response.statusCode}");
//      }
//    } on DioError catch (e) {
//      /// 打印请求失败相关信息
//      print("【请求出错】${e.toString()}");
//      onError(e.toString());
//    }
//    return result;
//  }
  /// 清空 dio 对象
  static clear() {
    dio = null;
  }
}

///日志拦截器
class LogInterceptors extends InterceptorsWrapper {
  @override
  Future onRequest(RequestOptions options) {
    print("【请求baseUrl】${options.baseUrl}");
    print("【请求path】${options.path}");
    print("【请求headers】${options.headers.toString()}");
    //todo 参数拦截
    print("【请求参数】${options.data.toString()}");
    return super.onRequest(options);
  }

  @override
  Future onResponse(Response response) {
    print("【返回statusCode】${response.statusCode}");
    print("【返回headers】${response.headers.toString()}");
    print("【返回extra】${response.extra.toString()}");
    print("【返回data】${response.data.toString()}");
    return super.onResponse(response);
  }

  @override
  Future onError(DioError err) {
    print(err.toString());
    print(err.response?.toString());
    return super.onError(err);
  }
}

相应基类定义

///convert和FlutterJsonBeanFactory结合解析
class BaseEntity<T> {
  T data;
  int errorCode;
  String errorMsg;

  BaseEntity({this.data, this.errorCode, this.errorMsg});

  BaseEntity.fromJson(Map<String, dynamic> json) {
    if (json['data'] != null&&json['data']!='null') {
      data = JsonConvert.fromJsonAsT<T>(json['data']);
    }
    errorCode = json['errorCode'];
    errorMsg = json['errorMsg'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.data != null) {
      data['data'] = this.data;
    }
    data['errorCode'] = this.errorCode;
    data['errorMsg'] = this.errorMsg;
    return data;
  }
}

JsonConvert.fromJsonAsT<T>(json['data']); 是FlutterJsonBeanFactory生成的,判断了Object或List类型分别解析

使用

HttpManager.getInstance().get("banner/json", null, (data) {
      BaseEntity<List<BannerEntity>> baseEntity = BaseEntity.fromJson(data);
      baseEntity.data.forEach((element) {
        print(element.imagePath);
      });
    }, (error) {
      ToastUtil.showToastCenter(error);
    });

post请求

var map = Map<String, String>();
    map["username"] = "江渚清沨";
    map["password"] = "xxxxx";
    FormData formData = FormData.fromMap(map);
    HttpManager.getInstance().post("user/login", formData, (data) {
      BaseEntity<UserEntity> baseModel = BaseEntity.fromJson(data);
      print("解析${baseModel.errorMsg}");
    }, (error) {
      ToastUtil.showToastCenter(error);
    });

代码地址  https://gitee.com/jiangzhuqingfeng/flutter_demo.git

猜你喜欢

转载自blog.csdn.net/jerry872235631/article/details/107104892