flutter 网络请求封装

总体的思路,

  1. 借助Dio,将其封装为一个工具类(dio_utils.dart)
  2. 封装请求服务(service_api.dart)
  3. 根据请求参数封装 请求model (RequireModel )
  4. 根据返回数据类型封装返回Entitiy(list_entity.dart。因为返回的data中是一个list,如果是一个string,直接在entiy中解析好,上层进行调用即可)
  5. data中的单个对象进行封装(PersionEntity),方便解析
  6. 使用

总的来说封装了这么多就是为了后期使用方便。

1、dio_utils.dart

import 'dart:async';
import 'package:dio/dio.dart';

import 'err_code.dart';
import 'method.dart';

class DioNetUtils {
  static final DioNetUtils _singleton = DioNetUtils._init();
  static Dio _dio;
  static const String text_type = "application/json; charset=utf-8";
  static const String from_type = "application/x-www-form-urlencoded";
  /// 是否是debug模式.
  static bool _isDebug = true;
  /// 打开debug模式.
  static void openDebug() {
    _isDebug = true;
  }

  DioNetUtils._init() {
    BaseOptions options = new BaseOptions(
      baseUrl: "https://www.baidu.com",
      connectTimeout: 1000 * 10,
      receiveTimeout: 1000 * 10,
      headers: {},
      //表示期望以那种格式(方式)接受响应数据。
      // 接受4种类型 `json`, `stream`, `plain`, `bytes`. 默认值是 `json`,
      responseType: ResponseType.json,
    );
    _dio = Dio(options);
    //添加拦截器
    _dio.interceptors.add(InterceptorsWrapper(
        onRequest: (RequestOptions options) {
          print("\n================== 请求数据 ==========================");
          print("url = ${options.uri.toString()}");
          print("headers = ${options.headers}");
          print("params = ${options.data}");
        },
        onResponse: (Response response) {
          print("\n================== 响应数据 ==========================");
          print("code = ${response.statusCode}");
          print("data = ${response.data}");
          print("\n");
        },
        onError: (DioError e) {
          print("\n================== 错误响应数据 ======================");
          print("type = ${e.type}");
          print("message = ${e.message}");
          print("\n");
        }
    ));
  }

  factory DioNetUtils() {
    return _singleton;
  }

  /// Make http request with options.
  /// [method] The request method.
  /// [path] The url path.
  /// [data] The request data
  /// [options] The request options.
  /// String 返回 json data .
  Future<Map<String,dynamic>> request<T>(
      String path, {
        String method = Method.get,
        String contentType = text_type,
        queryParameters,
        Options options,
        // CancelToken cancelToken,
      }) async {
    print('path===' + path);
    Response response;
    if (method == Method.get) {
      //GET方式
      response = await _dio.request(
        path,
        queryParameters: queryParameters,
        options: _checkOptions(method, contentType, options),
        // cancelToken: cancelToken,
      );
    } else {
      //除GET的其他方式
      var requestData;
      print(contentType);
      if (contentType == from_type) { //表单方式
        requestData = new FormData.fromMap({
          "key": "value"
        });
      } else { //json格式
        requestData = queryParameters;
      }
      response = await _dio.request(
        path,
        data: requestData,
        options: _checkOptions(method, contentType, options),
        // cancelToken: cancelToken,
      );
    }

    _printHttpLog(response);
    print('response.statusCode = ${response.statusCode}');
    if (response.statusCode == 200) {
      try {
        if (response.data is Map) {
          print('response.data["code"] = ${response.data["code"]}');
          // 由于不同的接口返回的格式不固定不规范,所以需要根据接口格式自定义.
          print('return response.data[\'data\'] = ${response.data['data']}');
          return response.data;
        } else if (response.data is List) {
          print('return List branch');
          return response.data;
        } else {
          print('return default else');
          return response.data;
        }
      } catch (e) {
        print('response error e =$e');
        return new Future.error(new DioError(
          response: response,
          type: DioErrorType.RESPONSE,
        ));
      }
    } else {
      //ShowToast.warning("网络连接不可用,请稍后重试");
      print('response defalut error....');
      new Future.error(new DioError(
        response: response,
        type: DioErrorType.RESPONSE,
      ));
    }
  }

  /// check Options.
  Options _checkOptions(method, contentType, options) {
    if (options == null) {
      options = new Options();
    }
    // if (contentType) {
    //   //设置请求的类型 json 表单
    //   options.contentType = contentType;
    // }
    options.method = method;
    return options;
  }

  // print Http Log.
  void _printHttpLog(Response response) {
    print(!_isDebug);
    if (!_isDebug) {
      return;
    }
    try {
      print("\n----------------Http Log Start----------------" +
          _getOptionsStr(response.request));
      print(response);
      print("\n----------------Http Log end----------------");
    } catch (ex) {
      print("\nHttp Log" + " error......");
    }
  }

  // get Options Str.
  String _getOptionsStr(RequestOptions request) {
    return "\nmethod: " +
        request.method +
        "\nbaseUrl: " +
        request.baseUrl +
        "\npath: " +
        request.path;
  }

  // 错误全局处理
  dealErrorInfo(DioError error) {
    print(error.type);
    // 请求错误处理
    Response errorResponse;
    if (error.response != null) {
      errorResponse = error.response;
    } else {
      errorResponse = new Response(statusCode: 201);
    }
    // 请求超时
    if (error.type == DioErrorType.CONNECT_TIMEOUT) {
      //ShowToast.warning("网络请求超时,请稍后重试");
      errorResponse.statusCode = ResultCode.CONNECT_TIMEOUT;
    }
    // 请求连接超时
    else if (error.type == DioErrorType.RECEIVE_TIMEOUT) {
      //ShowToast.warning("网络连接超时,请稍后重试");
      errorResponse.statusCode = ResultCode.RECEIVE_TIMEOUT;
    }
    // 服务器错误
    else if (error.type == DioErrorType.RESPONSE) {
      //ShowToast.warning("服务器繁忙,请稍后重试");
      errorResponse.statusCode = ResultCode.RESPONSE;
    }
    // 一般服务器错误
    else {
      //ShowToast.warning("网络连接不可用,请稍后重试1");
      errorResponse.statusCode = ResultCode.DEFAULT;
    }
    return errorResponse;
  }
}

err_code.dart

/*
 * dio网络请求失败的回调错误码 自定义
 */
class ResultCode {
  //正常返回是1
  static const SUCCESS = 1;

  //异常返回是0
  static const ERROR = 0;

  /// When opening  url timeout, it occurs.
  static const CONNECT_TIMEOUT = -1;

  ///It occurs when receiving timeout.
  static const RECEIVE_TIMEOUT = -2;

  /// When the server response, but with a incorrect status, such as 404, 503...
  static const RESPONSE = -3;

  /// When the request is cancelled, dio will throw a error with this type.
  static const CANCEL = -4;

  /// read the DioError.error if it is not null.
  static const DEFAULT = -5;
}

method.dart

/// 请求方法.
class Method {
  static const String get = "GET";
  static final String post = "POST";
  static final String put = "PUT";
  static final String head = "HEAD";
  static final String delete = "DELETE";
  static final String patch = "PATCH";
}

2、service_api.dart 请求服务封装

import 'dart:async';

import 'package:dio/dio.dart';

import 'common/dio_utils.dart';
import 'common/method.dart';

class ServiceNetApi {

  Future<Map> getPersons(data) async {
    return await DioNetUtils().request<String>(
        "/pwd/peoples",
        queryParameters:data,
        method:Method.get
    );
  }
}

3、请求参数Model封装

import 'package:flutter/material.dart';

class RequireModel {

  String prov;
  String parm;

  RequireModel ({
    @required this.prov,  // 必须传递的参数使用@require修饰
    this.parm
  });

  /// 实体类转 Map
  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['prov'] = this.prov;
    data['parm'] = this.parm;
    return data;
  }
}

返回数据

{
    "code": 0,
    "data": [
        {
            "addr": "shanghai",
            "name": "java"
        },
        {
            "addr": "beijing",
            "name": "c"
        }
    ],
    "msg": "success"
}

4、list_entity.dart 封装如下 

class ListEntity {

  int code;
  List<dynamic> data;
  String msg;

  /// Map 转实体类
  ListEntity.fromJson(Map<String, dynamic> json) {
    this.code = json['code'];
    this.data = json['data'];
    this.msg = json['msg'];
  }

}

5、返回的一个people_entity.dart  Model 对象封装

class PersionEntity {

  String name;
  String addr;

  /// Map 转实体类
  PersionEntity.fromJson(Map<String, dynamic> json) {
    this.name= json['name'];
    this.addr= json['addr'];
  }
}

6、使用

void _getPeopleInfos() async {
    await ServiceNetApi()
        .getPersons(RequireModel(prov:'aa',parm:'bb').toJson())
        .then((value) {
      ListEntity entity = ListEntity.fromJson(value);
      if (entity.code == 0) {
        /// 解析数据
        List<PersionEntity > list = entity.data
            .map((e) => PersionEntity.fromJson((e as Map<String, dynamic>)))
            .toList();
        // do something...
        setState(() {});
      } else {
        print('get failed');
      }
    }).catchError((e) {
      print('get failed e = $e');
    });
  }

 

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值