Flutter使用Dio包网络请求进行封装以及如何将网络数据转化为模型数据便捷方法

761 阅读2分钟

一、基于Dio网络请求封装

1、创建一个request.dart的文件

import 'package:dio/dio.dart';

class XTXRequestManager {
  Dio? _dio;
  // 1.私有属性
  static XTXRequestManager? _instance;
  // 2.私有的命名构造函数;用于实例化对象
  XTXRequestManager._initManager() {
    // 如果dio为空就创建dio实例
    if (_dio == null) {
      // 请求基础配置信息
      BaseOptions baseOptions = BaseOptions(
          connectTimeout:
              const Duration(milliseconds: 15000), //int类型转化为Dutration类型
          receiveTimeout: const Duration(milliseconds: 5000),
          baseUrl: '你的接口基础地址');
      _dio ??= Dio(baseOptions);
      // 设置dio插件的拦截器
      _dio!.interceptors.add(InterceptorsWrapper(
        onRequest: (RequestOptions options, RequestInterceptorHandler handler) {
          // 发送请求前的拦截操作,以及发送前的一些逻辑的处理
          // 1.设置请求头
          options.headers = {
            "Authorization": '', //设置用户身份信息
            "source-client": 'app' //客户端类型
          };
          return handler.next(options);
        },
        onResponse: (Response e, ResponseInterceptorHandler handler) {
          //接受响应前的操作,以及接受数据之后的一些操作
          return handler.next(e);
        },
        onError: (DioError e, ErrorInterceptorHandler handler) {
          //捕获到异常的拦截操作,统一的异常处理(用户信息过期了,后端会返回状态码401,如果拦截到401,可以统一处理401的问题)
          return handler.next(e);
        },
      ));
    }
  }
  // 3.创建单例对象是否存在,如果不存在,新建单例对象,反之,直接返回单例对象
  factory XTXRequestManager() {
    _instance ??= XTXRequestManager._initManager();
    return _instance!;
  }
  // 处理请求的公共方法
  handelRequest(String path, String method,
      {data, Map<String, String>? queryParameters}) {
    return _dio!.request(path,
        data: data,
        queryParameters: queryParameters,
        options: Options(method: method));
  }
}

2、建议每个页面的接口创建一个dart文件(首页为例)

import 'package:app_view/model/home_page_demo.dart';
import 'package:app_view/service/request.dart';
import 'package:dio/dio.dart';

class HomeApI {
  static Future<Result> homeFetch() async {
    Response res = await XTXRequestManager().handelRequest('home/index', "GET");
    HomePageDemo homepage = HomePageDemo.fromJson(res.data);
    return homepage.result;
  }
}

这里导入的home_page_demo.dart文件如果采用手动将网络数据转化为模型数据

假设接口返回的数据是

{
    "code": "1",
    "msg": "操作成功",
    "result": {
        "list1": [
            {
                "id": "1",
                "imgUrl": "http://XXXX.jpg",
            }
           ],
         "list2":[],
         "list3":[]
        }
 }

手动处理的结果是这样

  // 1.模型属性
  final List? list1;
  final List? list2;
  final List? list3;
  // 2.构造函数
  HomeModel(
      {this.list1,
      this.list2,
      this.list3,
    });
  // 3.工厂函数
  factory HomeModel.fromJson(Map<String, dynamic> json) {
    // 获取轮播图列表
    List imageBannersJson = json['imageBanners'];
    List imageBanners = [];
    imageBannersJson.forEach((element) {
      imageBanners.add(imageBannersModel.fromJson(element));
    });
    return HomeModel(
        list1: imageBanners,
        list2: [],
        list3: [],
     );
  }
}

class imageBannersModel {
  final String id;
  final String imgUrl;
  imageBannersModel(
      {required this.id,
      required this.imgUrl
      });
  factory imageBannersModel.fromJson(Map<String, dynamic> json) {
    return imageBannersModel(
        id: json['id'],
        imgUrl: json['imgUrl'],
  }
}

目前处理的只是普通的结构数据,如果是嵌套数据的话,我们手动处理起来效率比较低,我推荐下面的一种方法 我在网上看到的链接blog.csdn.net/WangQingLei…

补充:

  • pubspec.yaml文件中引入build_runnerjson_serializable两个包,尽量下载适合自己项目的版本