Flutter Http请求库 dio 代码封装

本文介绍了一个基于Flutter的Http请求库dio的封装实现——HttpUtils.dart。该库提供了RESTful请求的GET、POST、DELETE、PATCH等方法的封装,统一处理了请求前缀、请求信息、响应信息及错误信息,适用于跨平台应用开发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源代码地址https://github.com/junkai-li/NetCoreKevin
基于NET6搭建跨平台WebApi架构支持单点登录、多缓存、自动任务、分布式、多租户、日志、授权和鉴权 、网关 注册与发现、CAP集成事件、领域事件、 docker部署

Flutter Http请求库 dio 代码封装

**

新增HttpUtils.dart

**

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

//**********************************************************************************
//
// 文件名称:HttpUtils.dart
//
/ 
//
// 创建日期:2020-01-07
//
// 文件描述:Dio 封装 restful 请求 GET、POST、DELETE、PATCH
// * 主要作用为统一处理相关事务:
//*  - 统一处理请求前缀;
//*  - 统一打印请求信息;
//*  - 统一打印响应信息;
//*  - 统一打印报错信息;
// 修改履历:
// ---------------------------------------------------------------------------------
// 修改日期     修改者  修改标识   修改描述 (首行为示例)
// 2020/1/7    李军凯             链接Api验证登陆账号密码
//
//**********************************************************************************
class HttpUtils {
  /// global dio object
  static Dio dio;

  /// default options
  static const String API_PREFIX = 'http://10.0.2.2/api';//10.0.2.2//127.0.0.1
  //请求时间
  static const int CONNECT_TIMEOUT = 10000;
  //响应时间
  static const int RECEIVE_TIMEOUT = 10000;

  /// 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';

  /// request method
  static Future<Map> request(String url,
      {data, method, contentTypeString}) async {
    data = data ?? {};
    method = method ?? 'GET';
    contentTypeString = contentTypeString ?? 'application/json;charset=UTF-8';

    /// 打印请求相关信息:请求地址、请求方式、请求参数
    print('请求地址:【' + method + '  ' + url + '】');
    print('请求参数:' + data.toString());
    
    clear();
    Dio dio = createInstance();

    var result; 

    try {

      Response response = await dio.request(url,
          data: data,
          options: new Options(method: method, contentType: contentTypeString));

      result = response.data;

      /// 打印响应相关信息
      print('响应数据:' + response.toString());
    } on DioError catch (e) {

      ErrorEntity en = new ErrorEntity().createErrorEntity(e); 
      /// 打印请求失败相关信息
      print('请求出错:' + en.message);

    }

    return result;
  }

  /// 创建 dio 实例对象
  static Dio createInstance() {
    if (dio == null) {
      /// 全局属性:请求前缀、连接超时时间、响应超时时间
      BaseOptions options = new BaseOptions(
        baseUrl: API_PREFIX,
        connectTimeout: CONNECT_TIMEOUT,
        receiveTimeout: RECEIVE_TIMEOUT, 
      );

      dio = new Dio(options);
    }

    return dio;
  }

  /// 清空 dio 对象
  static clear() {
    dio = null;
  }
}

//请求错误类
class ErrorEntity {
  int code;
  String message;

  ErrorEntity({this.code, this.message});

  // 错误信息
  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);
        }
    }
  }
}

如何使用?

 var result = await HttpUtils.request(
                                '/MoveApp/AppLogin',
                                method: HttpUtils.POST,
                                data: {'name': _name, 'password': _pwd});
<think>好的,用户想了解如何在Flutter中使用Dio进行网络请求的简单封装。首先,我需要回顾Dio的基本用法,然后思考如何有效地封装它以提高代码复用性和可维护性。用户提供的引用内容提到封装时需要注意返回类型的处理,比如Response和BaseModel的区别,还有错误处理和加载体验。这些点都需要在回答中涵盖。 首先,我应该介绍Dio的基本配置,比如设置baseUrl和超时时间。然后,可能需要添加拦截器来处理请求和响应,比如添加Loading动画和统一错误处理。接着,封装GET和POST方法是常见的需求,用户可能需要示例代码来参考。此外,引用中的项目地址和详细步骤提示我应该提供一个结构化的封装示例,可能包括单例模式、拦截器、请求方法封装以及模型转换。 用户可能对错误处理的具体实现比较关注,比如如何捕获DioException并转换为友好的错误提示。同时,返回类型的处理,如使用泛型和BaseModel来解析数据,也是关键点。需要确保示例代码符合最新的Dio版本,并且注释清晰,方便用户理解。 另外,用户提供的引用提到维护和使用的方便性,所以封装后的方法应该简洁易用。可能需要提到如何调用封装后的方法,比如使用DioManager单例,并处理不同的响应类型。最后,生成的相关问题需要与封装的不同方面相关,比如性能优化、错误处理扩展和模型转换方法,这样用户可以有进一步学习的路径。 总结下来,回答需要分步骤讲解封装的各个部分,提供代码示例,并引用提供的资料来支持关键点,比如错误处理和模型转换。同时,确保代码格式正确,使用$...$和$$...$$标记数学表达式(虽然在这个问题中可能用不到,但需要留意)。最后,生成的相关问题要帮助用户深入探索封装的其他方面。</think>### Flutter Dio网络请求封装步骤 #### 1. 基础配置 ```dart class DioManager { static final DioManager _instance = DioManager._internal(); late Dio _dio; factory DioManager() => _instance; DioManager._internal() { _dio = Dio(BaseOptions( baseUrl: "https://api.example.com", connectTimeout: const Duration(seconds: 15), receiveTimeout: const Duration(seconds: 15), )); _addInterceptors(); // 添加拦截器[^2] } } ``` #### 2. 拦截器封装(含错误处理) ```dart void _addInterceptors() { _dio.interceptors.add(InterceptorsWrapper( onRequest: (options, handler) { // 显示Loading弹窗 showLoading(); return handler.next(options); }, onError: (DioException error, handler) async { // 统一错误处理 hideLoading(); _handleError(error); return handler.next(error); }, onResponse: (response, handler) { // 隐藏Loading hideLoading(); return handler.next(response); } )); } void _handleError(DioException error) { String message = "网络异常"; if (error.type == DioExceptionType.connectionTimeout) { message = "连接超时"; } // 显示Toast提示 showToast(message); } ``` #### 3. 请求方法封装 ```dart // GET请求封装 Future<T> get<T>(String path, {Map<String, dynamic>? params}) async { try { final response = await _dio.get(path, queryParameters: params); return _parseResponse<T>(response); // 使用泛型解析响应[^4] } on DioException catch (e) { throw _handleError(e); } } // POST请求封装 Future<T> post<T>(String path, {dynamic data}) async { try { final response = await _dio.post(path, data: data); return _parseResponse<T>(response); } on DioException catch (e) { throw _handleError(e); } } ``` #### 4. 响应解析(支持模型转换) ```dart T _parseResponse<T>(Response response) { if (T == Response) return response as T; // 直接返回原始响应 final baseModel = BaseModel.fromJson(response.data); if (baseModel.code != 200) { throw AppError(baseModel.message); } if (T == BaseModel) return baseModel as T; return _convertModel<T>(baseModel.data); // 自定义模型转换方法 } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值