Flutter用dio封装http网络请求,设置统一的请求地址、headers及处理返回内容

时间:2021-10-07 02:10:29

封装http请求是项目中经常需要做的,常用于设置通用请求地址、请求headers以及处理返回结果,例如在项目中开发地址、测试地址、上线地址是不一样的,当在封装的请求设置好默认地址之后只需要改一个地址而不需要每一个接口都去修改,以及统一在headers设置token用来校验身份等。

先来看一下完成后的使用方法把(格式是不是有点像ajax)

HttpUtil.get(
url,
data: {
key: value
},
headers: {
  key: value
 }
success: (data){
// 请求成功返回的数据
},error: (errorMsg){
// 请求失败返回的错误信息
}
);

  

封装实现

使用dio先在pubspec.yaml添加dio包,然后packages get,获取最新的版本https://pub.dev/packages/dio

dio: ^2.1.7

  

然后在封装的地方引用它

import 'package:dio/dio.dart';

  

在页面中先设置一个请求地址

class BaseUrl{
// 配置默认请求地址
static const String url = 'http://127.0.0.1';
}

  

再建立一个HttpUtil类,把请求方法写在里面,先来实现一下get请求,在方法中写好可接收的参数,url必填其他选填

class HttpUtil{
static void get(
String url,
{
Map<String, dynamic> data,
Map<String, dynamic> headers,
Function success,
Function error
}
) async {
// 对接收到的请求参数进行从处理
}
}

  

在get请求中携带参数的用字符串拼接的形式例如:http://127.0.0.1/vod/getPlayInfo?userid=bd2439487ce6540a68ce01b8f57242eb6&number=5,所以在接收到请求携带的参数后如果请求参数不为空需要对携带的参数其进行拼接处理

// 数据拼接
if(data != null && data.isNotEmpty){
StringBuffer options= new StringBuffer('?');
data.forEach((key, value){
options.write('${key}=${value}&');
});
String optionsStr = options.toString();
optionsStr = optionsStr.substring(0, optionsStr.length - 1);
url += optionsStr;
}

  

数据拼接完成之后即可发起请求,把请求写到一个_sendRequest方法中,然后进行进一步的处理

// 发送get请求
await _sendRequest(
url,
'get',
success,
headers: headers,
error: error
);

  

在写_sendRequest方法之前先看后端返回格式,我这边的返回格式是这样的,当请求成功后端code返回0,失败会返回其他失败码及提示信息

{
"code": 0, // int
"msg": "后端返回失败提示信息", // string
"data": {} // 这可能是对象,也可能数数组
}

  

下面来实现_sendRequest方法,当获取到请求的url后进行判断,如果url是以http开头的就可认为其是完整地址,那就直接使用传过来的地址,如果不是以http开头的,那就使用设置的默认地址来拼接请求地址

// 请求处理
static Future _sendRequest(
String url,
String method,
Function success,
{
Map<String, dynamic> data,
Map<String, dynamic> headers,
Function error
}
) async {
int _code;
String _msg;
var _backData; // 检测请求地址是否是完整地址
if(!url.startsWith('http')){
url = BaseUrl.url + url;
} }

  

发起请求

在请求之前先判断data和headers是否为空,然后配置dio的请求信息,查看dio更多API:https://github.com/flutterchina/dio

try{
Map<String, dynamic> dataMap = data == null ? new Map() : data;
Map<String, dynamic> headersMap = headers == null ? new Map() : headers; // 配置dio请求信息
Response response;
Dio dio = new Dio();
dio.options.connectTimeout = 10000; // 服务器链接超时,毫秒
dio.options.receiveTimeout = 3000; // 响应流上前后两次接受到数据的间隔,毫秒
dio.options.headers.addAll(headersMap); // 添加headers,如需设置统一的headers信息也可在此添加 if(method == 'get'){
response = await dio.get(url);
}else{
response = await dio.post(url,data: dataMap);
} }catch(exception){
_handError(error, '数据请求错误:'+exception.toString());
}

  

请求结果处理

先判断请求状态是否为200,否则返回请求错误;然后看后端返回的code是否为0,不为0则返回状态吗+错误信息

if(response.statusCode != 200){
_msg = '网络请求错误,状态码:' + response.statusCode.toString();
_handError(error, _msg);
return;
} // 返回结果处理
Map<String, dynamic> resCallbackMap = response.data;
_code = resCallbackMap['code'];
_msg = resCallbackMap['msg'];
_backData = resCallbackMap['data']; if(success != null){
if(_code == 0){
success(_backData);
}else{
String errorMsg = _code.toString()+':'+_msg;
_handError(error, errorMsg);
}
}

  

最后再写一个返回错误信息的方法

// 返回错误信息
static Future _handError(Function errorCallback,String errorMsg){
if(errorCallback != null){
errorCallback(errorMsg);
}
}

  

完成后测试一下一个get请求,测试的json如下

{
"code": 0,
"msg": "",
"data": {
"backResult": "返回成功啦"
}
}

  

请求代码

HttpUtil.get(
'/app_model/httptest.json',
success: (data){
print(data.toString());
},error: (errorMsg){
print(errorMsg);
}
);

  

返回结果如下:

I/flutter ( 7871): {backResult: 返回成功啦}

  

完整代码

源文件可以到git获取https://gitee.com/daydayfull/flutter_httputil

import 'package:dio/dio.dart';

class BaseUrl{
// 配置默认请求地址
static const String url = 'http://127.0.0.1';
} class HttpUtil{
static void get(
String url,
{
Map<String, dynamic> data,
Map<String, dynamic> headers,
Function success,
Function error
}
) async { // 数据拼接
if(data != null && data.isNotEmpty){
StringBuffer options= new StringBuffer('?');
data.forEach((key, value){
options.write('${key}=${value}&');
});
String optionsStr = options.toString();
optionsStr = optionsStr.substring(0, optionsStr.length - 1);
url += optionsStr;
} // 发送get请求
await _sendRequest(
url,
'get',
success,
headers: headers,
error: error
);
} static void post(
String url,
{
Map<String, dynamic> data,
Map<String, dynamic> headers,
Function success,
Function error
}
) async { // 发送post请求
_sendRequest(
url,
'post',
success,
data: data,
headers: headers,
error: error
);
} // 请求处理
static Future _sendRequest(
String url,
String method,
Function success,
{
Map<String, dynamic> data,
Map<String, dynamic> headers,
Function error
}
) async {
int _code;
String _msg;
var _backData; // 检测请求地址是否是完整地址
if(!url.startsWith('http')){
url = BaseUrl.url + url;
} try{
Map<String, dynamic> dataMap = data == null ? new Map() : data;
Map<String, dynamic> headersMap = headers == null ? new Map() : headers; // 配置dio请求信息
Response response;
Dio dio = new Dio();
dio.options.connectTimeout = 10000; // 服务器链接超时,毫秒
dio.options.receiveTimeout = 3000; // 响应流上前后两次接受到数据的间隔,毫秒
dio.options.headers.addAll(headersMap); // 添加headers,如需设置统一的headers信息也可在此添加 if(method == 'get'){
response = await dio.get(url);
}else{
response = await dio.post(url,data: dataMap);
} if(response.statusCode != 200){
_msg = '网络请求错误,状态码:' + response.statusCode.toString();
_handError(error, _msg);
return;
} // 返回结果处理
Map<String, dynamic> resCallbackMap = response.data;
_code = resCallbackMap['code'];
_msg = resCallbackMap['msg'];
_backData = resCallbackMap['data']; if(success != null){
if(_code == 0){
success(_backData);
}else{
String errorMsg = _code.toString()+':'+_msg;
_handError(error, errorMsg);
}
} }catch(exception){
_handError(error, '数据请求错误:'+exception.toString());
}
} // 返回错误信息
static Future _handError(Function errorCallback,String errorMsg){
if(errorCallback != null){
errorCallback(errorMsg);
}
}
}

  

这里只简单写了get和post两个方法,在dio中提供了如下方法

Future get(...)

Future post(...)

Future put(...)

Future delete(...)

Future head(...)

Future put(...)

Future path(...)

Future download(...)

  

Flutter用dio封装http网络请求,设置统一的请求地址、headers及处理返回内容的更多相关文章

  1. Retrofit2&period;0&plus;OkHttp设置统一的请求头&lpar;request headers&rpar;

    有时候要求Retrofit2的接口中每个都要增加上headers,又不想做重复的事情,可以使用这种方法来为每个request请求都设置上相同的请求头header. 修改请求头request heade ...

  2. Android okHttp网络请求之Get&sol;Post请求

    前言: 之前项目中一直使用的Xutils开源框架,从xutils 2.1.5版本使用到最近的xutils 3.0,使用起来也是蛮方便的,只不过最近想着完善一下app中使用的开源框架,由于Xutils里 ...

  3. Vue--axios:vue中的ajax异步请求(发送和请求数据)、vue-resource异步请求和跨域

    跨域原理: 一.使用axios发送get请求 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 & ...

  4. 基于AFNetworking封装的网络请求工具类【原创】

    今天给大家共享一个我自己封装的网络请求类,希望能帮助到大家. 前提,导入AFNetworking框架, 关于修改AFN源码:通常序列化时做对text/plan等的支持时,可以一劳永逸的修改源代码,在a ...

  5. iOS 自己封装的网络请求,json解析的类

    基本上所有的APP都会涉及网络这块,不管是用AFNetWorking还是自己写的http请求,整个网络框架的搭建很重要. 楼主封装的网络请求类,包括自己写的http请求和AFNetWorking的请求 ...

  6. Flutter实战视频-移动电商-05&period;Dio基础&lowbar;引入和简单的Get请求

    05.Dio基础_引入和简单的Get请求 博客地址: https://jspang.com/post/FlutterShop.html#toc-4c7 第三方的http请求库叫做Dio https:/ ...

  7. Flutter之Dio引入和简单的Get&sol;Post请求

    先在pubspec.yaml中引入Dio包如图所示 认识Dio库:dio是一个dart的 http请求通用库,目前也是大陆使用最广泛的库,国人开发,完全开源. flutter的插件包管理:学了引入di ...

  8. iOS-AFNetworking封装Get&lpar;自定义HTTP Header&rpar;和Post请求及文件下载

    前面提到AFNetworking是一个很强大的网络三方库,首先你需要引入AFNetworking三方库:如封装的有误还请指出,谢谢! 1.Get请求 /**Get请求 url 服务器请求地址 succ ...

  9. 教你如何封装异步网络连接NSURLConnection实现带有百分比的下载

    教你如何封装异步网络连接NSURLConnection实现带有百分比的下载 注:本教程需要你对block有着较为深刻的理解,且对如何封装对象有着一些经验. 也许你已经用惯了AFNetworking2. ...

随机推荐

  1. 2014 UESTC暑前集训图论专题解题报告

    A.方老师和缘分 http://www.cnblogs.com/whatbeg/p/3765621.html B.方老师和农场 http://www.cnblogs.com/whatbeg/p/376 ...

  2. 转 -- linux IO子系统和文件系统读写流程

    我们含有分析的,是基于2.6.32及其后的内核. 我们在linux上总是要保存数据,数据要么保存在文件系统里(如ext3),要么就保存在裸设备里.我们在使用这些数据的时候都是通过文件这个抽象来访问的, ...

  3. Ajax中eval的使用详解

    定义和用法 Eval它是用来计算某个字符串,并且执行其中的JavaScript代码. 语法 1) eval函数接受一个string这个参数,并且这个参数是必须的,这个参数就是要计算的这个字符串.它里面 ...

  4. Eclipse使用git最简易流程

    git有诸多好处,网上都说的很清楚了,在这里我不再赘述.对于我来说,私下里想做一些项目,而又不能很好的保存自己的代码和进行版本控制,这时候,就用到了git.下面,就以我个人为例讲讲git从0开始如何安 ...

  5. Selenium - 搭建环境

    1. 在Python中安装第三方库 1)安装Selenium 通过pip安装   2). 下载geckodriverckod 从selenium3开始,webdriver/firefox/webdri ...

  6. shell脚本--输入与输出

    输出带有转义字符的内容 单独一个echo表示一个换行 使用echo输出时,每一条命令之后,都默认加一个换行:要想取消默认的换行,需要加 -n 参数. #!/bin/bash #文件名:test.sh ...

  7. 【Java】经典示例代码

    成鹏致远 | lcw.cnblogs.com | 2014-02-08 单例设计模式 class Singleton{ private static Singleton instance = new ...

  8. 【Unity 3D】碰撞检测

    在unity3d中,能检测碰撞发生的方式有两种, 碰撞器 触发器 概念:     (一)碰撞器是一群组件,它包含了很多种类,比如:Box Collider,Capsule Collider等,这些碰撞 ...

  9. 《Lua程序设计》第6章 深入函数 学习笔记

    在Lua中,函数是一种“第一类值(First-Class Value)”,它们具有特定的词法域(Lexical Scoping).“词法域”:函数可以潜逃在另一个函数中,内部的函数可以访问外部函数中的 ...

  10. 浏览器兼容性工具 Spoon Browser Sandbox

    1.Spoon Browser Sandbox 勺浏览器沙箱 主流浏览器多(IE.Chrome.FireFox.Safari.Opera),浏览器又有很多版本:保证网页在主流浏览器中很好的显示,不可能 ...