Flutter Dio二次封装的实现

目录:

  • DioManager:Dio辅助类NWMethod:请求方法,get、post等
  • NWApi:大家都知道
  • EntityFactory:json转换辅助工厂,把json转为T
  • BaseEntity<T>:数据基类,返回的参数为 {“code”: 0, “message”: “”, “data”: {}}
  • BaseListEntity<T>:数据基类2,返回的参数为 {“code”: 0, “message”: “”, “data”: []}
  • ErrorEntity:请求报错基类,{“code”: 0, “message”: “”}

EntityFactory:

class EntityFactory {
 static T generateOBJ<T>(json) {
  if (json == null) {
   return null;
  }
//可以在这里加入任何需要并且可以转换的类型,例如下面
//  else if (T.toString() == "LoginEntity") {
//   return LoginEntity.fromJson(json) as T;
//  }
  else {
   return json as T;
  }
 }
}

BaseEntity:

class BaseEntity<T> {
 int code;
 String message;
 T data;

 BaseEntity({this.code, this.message, this.data});

 factory BaseEntity.fromJson(json) {
  return BaseEntity(
   code: json["code"],
   message: json["msg"],
   // data值需要经过工厂转换为我们传进来的类型
   data: EntityFactory.generateOBJ<T>(json["data"]),
  );
 }
}

BaseListEntity:

class BaseListEntity<T> {
 int code;
 String message;
 List<T> data;

 BaseListEntity({this.code, this.message, this.data});

 factory BaseListEntity.fromJson(json) {
  List<T> mData = List();
  if (json['data'] != null) {
   //遍历data并转换为我们传进来的类型
   (json['data'] as List).forEach((v) {
    mData.add(EntityFactory.generateOBJ<T>(v));
   });
  }

  return BaseListEntity(
   code: json["code"],
   message: json["msg"],
   data: mData,
  );
 } }

ErrorEntity:

class ErrorEntity {
 int code;
 String message;
 ErrorEntity({this.code, this.message});
}

NWApi:

class NWApi {
 static final baseApi = "https://easy-mock.bookset.io/mock/5dfae67d4946c20a50841fa7/example/";
 static final loginPath = "user/login";//接口返回:{"code": int, "message": "String", "data": {"account": "String", "password": "String"}}
 static final queryListPath = "/query/list";//接口返回:{"code": ing, "message": "String", "data": [int, int, String, int, String, int]}
 static final queryListJsonPath = "/query/listjson";//接口返回:{"code": int, "message": "String", "data": [{"account": "String", "password": "String"}, {"account": "String", "password": "String"}]}
}

NWMethod:

enum NWMethod {
 GET,
 POST,
 DELETE,
 PUT
}
//使用:NWMethodValues[NWMethod.POST]
const NWMethodValues = {
 NWMethod.GET: "get",
 NWMethod.POST: "post",
 NWMethod.DELETE: "delete",
 NWMethod.PUT: "put"
};

下面就可以进行正式的封装了:

第一步是创建Dio的单例辅助类,并初始化Dio和对Dio进行一些全局的参数设置:

import 'package:dio/dio.dart';
import 'package:flutter_app/network/NWApi.dart';
import 'package:flutter_app/utils/PrintUtil.dart';
class DioManager {
 static final DioManager _shared = DioManager._internal();
 factory DioManager() => _shared;
 Dio dio;
 DioManager._internal() {
  if (dio == null) {
   BaseOptions options = BaseOptions(
    baseUrl: NWApi.baseApi,
    contentType: Headers.jsonContentType,
    responseType: ResponseType.json,
    receiveDataWhenStatusError: false,
    connectTimeout: 30000,
    receiveTimeout: 3000,
   );
   dio = Dio(options);
  }
 }
}

第二步对请求进行封装,在我的想法中 {“code”: 0, “message”: “”, “data”: {}} 和 {“code”: 0, “message”: “”, “data”: []} 这两种数据是要分开两个请求方法的:

 // 请求,返回参数为 T
 // method:请求方法,NWMethod.POST等
 // path:请求地址
 // params:请求参数
 // success:请求成功回调
 // error:请求失败回调
 Future request<T>(NWMethod method, String path, {Map params, Function(T) success, Function(ErrorEntity) error}) async {
  try {
   Response response = await dio.request(path, queryParameters: params, options: Options(method: NWMethodValues[method]));
   if (response != null) {
    BaseEntity entity = BaseEntity<T>.fromJson(response.data);
    if (entity.code == 0) {
     success(entity.data);
    } else {
     error(ErrorEntity(code: entity.code, message: entity.message));
    }
   } else {
    error(ErrorEntity(code: -1, message: "未知错误"));
   }
  } on DioError catch(e) {
   error(createErrorEntity(e));
  }
 }

 // 请求,返回参数为 List
 // method:请求方法,NWMethod.POST等
 // path:请求地址
 // params:请求参数
 // success:请求成功回调
 // error:请求失败回调
 Future requestList<T>(NWMethod method, String path, {Map params, Function(List) success, Function(ErrorEntity) error}) async {
  try {
   Response response = await dio.request(path, queryParameters: params, options: Options(method: NWMethodValues[method]));
   if (response != null) {
    BaseListEntity entity = BaseListEntity<T>.fromJson(response.data);
    if (entity.code == 0) {
     success(entity.data);
    } else {
     error(ErrorEntity(code: entity.code, message: entity.message));
    }
   } else {
     error(ErrorEntity(code: -1, message: "未知错误"));
   }
  } on DioError catch(e) {
   error(createErrorEntity(e));
  }
 }

提取请求错误处理方法createErrorEntity:

 // 错误信息
 ErrorEntity createErrorEntity(DioError error) {
  switch (error.type) {
   case DioErrorType.CANCEL:{
    return ErrorEntity(code: -1, message: "请求取消");
   }
   break;
   case DioErrorType.CONNECT_TIMEOUT:{
    return ErrorEntity(code: -1, message: "连接超时");
   }
   break;
   case DioErrorType.SEND_TIMEOUT:{
    return ErrorEntity(code: -1, message: "请求超时");
   }
   break;
   case DioErrorType.RECEIVE_TIMEOUT:{
    return ErrorEntity(code: -1, message: "响应超时");
   }
   break;
   case DioErrorType.RESPONSE:{
    try {
     int errCode = error.response.statusCode;
     String errMsg = error.response.statusMessage;
     return ErrorEntity(code: errCode, message: errMsg);
//     switch (errCode) {
//      case 400: {
//       return ErrorEntity(code: errCode, message: "请求语法错误");
//      }
//      break;
//      case 403: {
//       return ErrorEntity(code: errCode, message: "服务器拒绝执行");
//      }
//      break;
//      case 404: {
//       return ErrorEntity(code: errCode, message: "无法连接服务器");
//      }
//      break;
//      case 405: {
//       return ErrorEntity(code: errCode, message: "请求方法被禁止");
//      }
//      break;
//      case 500: {
//       return ErrorEntity(code: errCode, message: "服务器内部错误");
//      }
//      break;
//      case 502: {
//       return ErrorEntity(code: errCode, message: "无效的请求");
//      }
//      break;
//      case 503: {
//       return ErrorEntity(code: errCode, message: "服务器挂了");
//      }
//      break;
//      case 505: {
//       return ErrorEntity(code: errCode, message: "不支持HTTP协议请求");
//      }
//      break;
//      default: {
//       return ErrorEntity(code: errCode, message: "未知错误");
//      }
//     }
    } on Exception catch(_) {
     return ErrorEntity(code: -1, message: "未知错误");
    }
   }
   break;
   default: {
    return ErrorEntity(code: -1, message: error.message);
   }
  }
 }

完整的 DioManager 类代码:

import 'package:dio/dio.dart';
import 'package:flutter_app/network/entity/BaseEntity.dart';
import 'package:flutter_app/network/entity/BaseListEntity.dart';
import 'package:flutter_app/network/entity/EntityFactory.dart';
import 'package:flutter_app/network/entity/ErrorEntity.dart';
import 'package:flutter_app/network/NWApi.dart';
import 'package:flutter_app/network/NWMethod.dart';
class DioManager {
 static final DioManager _shared = DioManager._internal();
 factory DioManager() => _shared;
 Dio dio;
 DioManager._internal() {
  if (dio == null) {
   BaseOptions options = BaseOptions(
    baseUrl: NWApi.baseApi,
    contentType: Headers.jsonContentType,
    responseType: ResponseType.json,
    receiveDataWhenStatusError: false,
    connectTimeout: 30000,
    receiveTimeout: 3000,
   );
   dio = Dio(options);
  }
 }

 // 请求,返回参数为 T
 // method:请求方法,NWMethod.POST等
 // path:请求地址
 // params:请求参数
 // success:请求成功回调
 // error:请求失败回调
 Future request<T>(NWMethod method, String path, {Map params, Function(T) success, Function(ErrorEntity) error}) async {
  try {
   Response response = await dio.request(path, queryParameters: params, options: Options(method: NWMethodValues[method]));
   if (response != null) {
    BaseEntity entity = BaseEntity<T>.fromJson(response.data);
    if (entity.code == 0) {
     success(entity.data);
    } else {
     error(ErrorEntity(code: entity.code, message: entity.message));
    }
   } else {
    error(ErrorEntity(code: -1, message: "未知错误"));
   }
  } on DioError catch(e) {
   error(createErrorEntity(e));
  }
 }

 // 请求,返回参数为 List
 // method:请求方法,NWMethod.POST等
 // path:请求地址
 // params:请求参数
 // success:请求成功回调
 // error:请求失败回调
 Future requestList<T>(NWMethod method, String path, {Map params, Function(List<T>) success, Function(ErrorEntity) error}) async {
  try {
   Response response = await dio.request(path, queryParameters: params, options: Options(method: NWMethodValues[method]));
   if (response != null) {
    BaseListEntity entity = BaseListEntity<T>.fromJson(response.data);
    if (entity.code == 0) {
     success(entity.data);
    } else {
     error(ErrorEntity(code: entity.code, message: entity.message));
    }
   } else {
    error(ErrorEntity(code: -1, message: "未知错误"));
   }
  } on DioError catch(e) {
   error(createErrorEntity(e));
  }
 }

 // 错误信息
 ErrorEntity createErrorEntity(DioError error) {
  switch (error.type) {
   case DioErrorType.CANCEL:{
    return ErrorEntity(code: -1, message: "请求取消");
   }
   break;
   case DioErrorType.CONNECT_TIMEOUT:{
    return ErrorEntity(code: -1, message: "连接超时");
   }
   break;
   case DioErrorType.SEND_TIMEOUT:{
    return ErrorEntity(code: -1, message: "请求超时");
   }
   break;
   case DioErrorType.RECEIVE_TIMEOUT:{
    return ErrorEntity(code: -1, message: "响应超时");
   }
   break;
   case DioErrorType.RESPONSE:{
    try {
     int errCode = error.response.statusCode;
     String errMsg = error.response.statusMessage;
     return ErrorEntity(code: "$errCode", message: errMsg);
//     switch (errCode) {
//      case 400: {
//       return ErrorEntity(code: errCode, message: "请求语法错误");
//      }
//      break;
//      case 403: {
//       return ErrorEntity(code: errCode, message: "服务器拒绝执行");
//      }
//      break;
//      case 404: {
//       return ErrorEntity(code: errCode, message: "无法连接服务器");
//      }
//      break;
//      case 405: {
//       return ErrorEntity(code: errCode, message: "请求方法被禁止");
//      }
//      break;
//      case 500: {
//       return ErrorEntity(code: errCode, message: "服务器内部错误");
//      }
//      break;
//      case 502: {
//       return ErrorEntity(code: errCode, message: "无效的请求");
//      }
//      break;
//      case 503: {
//       return ErrorEntity(code: errCode, message: "服务器挂了");
//      }
//      break;
//      case 505: {
//       return ErrorEntity(code: errCode, message: "不支持HTTP协议请求");
//      }
//      break;
//      default: {
//       return ErrorEntity(code: errCode, message: "未知错误");
//      }
//     }
    } on Exception catch(_) {
     return ErrorEntity(code: -1, message: "未知错误");
    }
   }
   break;
   default: {
    return ErrorEntity(code: -1, message: error.message);
   }
  }
 }
}

使用:

// 返回 LoginEntity
DioManager().request<LoginEntity>(
 NWMethod.POST,
 NWApi.loginPath,
 params: {"account": "421789838@qq.com", "password": "123456"},
 success: (data) {
   print("success data = $data"});
 }, error: (error) {
   print("error code = ${error.code}, massage = ${error.message}");
 }
);

// 返回 List
DioManager().requestList<LoginEntity>(
 NWMethod.POST,
 NWApi.queryListJsonPath,
 params: {"account": "421789838@qq.com", "password": "123456"},
 success: (data) {
   print("success data = $data"});
 }, error: (error) {
   print("error code = ${error.code}, massage = ${error.message}");
 }
);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android Studio下Flutter环境搭建图文教程

    一.Flutter介绍 Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面.Flutter可以与现有的代码一起工作.在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费.开源的. 二.环境搭建 Flutter 的环境搭建⼗分省⼼,特别对应Android开发者⽽⾔,只是在AndroidStuido上安装 插件,并下载flutterSdk到本地,配置在环境变量即可,其实 中⽂⽹的搭建Futter开发环境 已经很贴⼼详细,从

  • 详解flutter之网络请求dio,请求,拦截器简单示例

    flutter一直很火的网络请求插件dio 直接上代码,写成一个类,可以直接使用 包含请求的封装,拦截器的封装 import 'package:dio/dio.dart'; import 'dart:async'; import 'dart:io'; import './apidomain.dart'; import './httpHeaders.dart'; import 'package:shared_preferences/shared_preferences.dart'; class D

  • Flutter Dio二次封装的实现

    目录: DioManager:Dio辅助类NWMethod:请求方法,get.post等 NWApi:大家都知道 EntityFactory:json转换辅助工厂,把json转为T BaseEntity<T>:数据基类,返回的参数为 {"code": 0, "message": "", "data": {}} BaseListEntity<T>:数据基类2,返回的参数为 {"code"

  • 详解Flutter中网络框架dio的二次封装

    其实dio框架已经封装的很好了,但是在实战项目中,为了项目可以统一管理,还是需要对dio框架进行二次封装. 整体思路:一般情况下,后台返回的数据我们可以分为两部分 1.状态数据 2.渲染数据 状态数据就是接口有没有正常返回数据相关的数据,这部分数据跟业务无关,我们可以封装起来统一管理,渲染数据就是我们渲染页面所需要的数据,这块的数据需要我们自己处理. 接下来我们就主要处理渲染数据这块的内容,我定义了两个函数,渲染数据可能为一个对象或者一个数组,我做了分别处理,定义两个函数来接受渲染数据. //

  • 关于二次封装jquery ajax办法示例详解

    前言 Ajax 的全称是Asynchronous JavaScript and XML 异步的javaScript和XML AJax所涉及到得技术: 1.使用CSS和XHTML来表示. 2. 使用DOM模型来交互和动态显示. 3.使用XMLHttpRequest来和服务器进行异步通信.(核心) 4.使用javascript来绑定和调用. 在我们前端处理数据的时候免不了要 ajax 与后台通信, ajax 是通过 XMLHttpRequest 对象与服务器进行通信的, jquery 在 XMLHt

  • IOS 使用Block二次封装AFNetworking 3.0详解

    IOS 使用Block二次封装AFNetworking 3.0详解 现在我们网络请求大都用第三方工具-–AFNetworking: 其中,AFNetworking 3.0 是对 NSURLSession 进行的封装,简化了很多步骤,但是在现实开发中,我们可以将AFNetworking再次封装到一个类中,这样通过传去URL和Parameters 就可以进行网络请求. 具体实现步骤: 前期准备:导入AFNetworking第三方框架 1.新建一个工具类,继承自NSObject: 2.在.h 中宏定义

  • Android基于OkHttpUtils网络请求的二次封装

    OkHttpUtils网络请求为什么进行二次封装? 1.减少代码量 2.后期换网络处理框架方便 二次封装的实现原理 1.将网络请求提取在一个方法中 2.对里面的可变参数,可以通过参数传递过去,也可以提供一个set方法传递过去 3.对于请求失败和成功,我们可以使用接口回调,让调用该方法的对象处理 封装后的网络处理类的功能 1.网络请求 2.xml数据转换成javaBean 每一个处理网络请求的ListView都要处理的3数据方法 1.初始化数据 2.下拉刷新数据 3.上拉加载数据 封装前的代码 /

  • 对jquery的ajax进行二次封装以及ajax缓存代理组件:AjaxCache详解

    虽然jquery的较新的api已经很好用了, 但是在实际工作还是有做二次封装的必要,好处有:1,二次封装后的API更加简洁,更符合个人的使用习惯:2,可以对ajax操作做一些统一处理,比如追加随机数或其它参数.同时在工作中,我们还会发现,有一些ajax请求的数据,对实时性要求不高,即使我们把第一次请求到的这些数据缓存起来,然后当相同请求再次发起时直接拿之前缓存的数据返回也不会对相关功能有影响,通过这种手工的缓存控制,减少了ajax请求,多多少少也能帮助我们提高网页的性能.本文介绍我自己关于这两方

  • Android 中Volley二次封装并实现网络请求缓存

    Android 中Volley二次封装并实现网络请求缓存 Android目前很多同学使用Volley请求网络数据,但是Volley没有对请求过得数据进行缓存,因此需要我们自己手动缓存. 一下就是我的一种思路,仅供参考 具体使用方法为: HashMap<String,String> params = new HashMap<>(); params.put("id", "1"); params.put("user", &quo

  • Vue二次封装axios为插件使用详解

    照例先贴上 axios的 gitHub 地址 不管用什么方式获取数据,对于一个项目来说,代码一定要利于维护其次是一定要写的优美,因此加上一层封装是必要的 vuejs2.0 已经不再维护 vue-resource,vuejs2.0 已经使用了 axios,这也是为什么我会转到 axios 的主要原因,废话不多说: 基本的封装要求: 统一 url 配置 统一 api 请求 request (请求)拦截器,例如:带上token等,设置请求头 response (响应)拦截器,例如:统一错误处理,页面重

  • 易语言是在VB6上二次开发或二次封装吗

    有朋友曾猜测易语言是在VB6基础上二次开发或二次封装的产品. 我在这里提几个思路可用于协助否定该猜测. VB6编译的程序在Windows 95系统内运行需要VB6运行库(MSVBVM60.dll直到Win98才被操作系统内置),而易语言编译的程序不需要该运行库. 易语言支持通过置入代码向目标编译程序输出x86机器码,而VB6没有类似的功能. 易语言支持静态编译EXE和DLL(非普通的打包然后在运行时释放DLL),而VB6没有类似的功能. 易语言支持直接使用C/C++的静态库(.lib/.obj)

  • 微信小程序表单验证插件WxValidate的二次封装功能(终极版)

    微信小程序表单验证前面的两篇文章做的效果总感觉都有点不太友好,第一篇里的效果是将错误信息通过对话框形式弹出来,这种形式在web形式下早已经淘汰了:第二篇是一次性全部显示所有的错误,然后3秒后自动消失, 这种在极端情况下也不太好,例如我例子里的一页的表单个数非常多的情况下,可能后面的还没看到就消失了.所以最近又重新做了一版,最终版的效果如下图:错误信息一次性全部显示,可以通过点击信息框让其消失,将自动消失时间设置的稍微长点,例如10秒,这样就能比较好的兼顾效果和使用上的便捷. 先讲讲最终版与前面2

随机推荐