Flutter之网络请求
Flutter之网络请求
一,介绍与需求
1.1,介绍
1,http一个可组合的,基于Future的库,用于发出HTTP请求。包含一组高级功能和类,可轻松使用HTTP资源。它与平台无关,可以在命令行和浏览器上使用。
2,Dart的功能强大的Http客户端,支持拦截器,全局配置,FormData,请求取消,文件下载,超时等。
1.2,需求
- Dart 原生的网络请求
HttpClient - 库
http - Flutter中文网发布的
dio
本文主要介绍后面两种网络请求方式的封装与使用,dart的原生网络请求HttpClient可参考文档通过HttpClient发起HTTP请求
二,网络请求封装
第一步:添加依赖
打开 pubspec.yaml文件,在dependencies下添加如下包:
http: ^0.12.+
dio: ^3.0.
保存后,一般会自动下载包;如果没有自动下载可在项目根目录下运行如下命令,进行下载:
flutter packages get
2.1,http请求库
第二步:引入包并创建网络请求类
import 'package:http/http.dart' as http;
class NetUtils {
...
}
第三步:get方式请求
// get请求的封装,传入的两个参数分别是请求URL和请求参数,请求参数以map的形式传入,会在方法体中自动拼接到URL后面
static Future<String> get(String url, {Map<String, String> params}) async {
if (params != null && params.isNotEmpty) {
// 如果参数不为空,则将参数拼接到URL后面
StringBuffer sb = StringBuffer("?");
params.forEach((key, value) {
sb.write("$key" + "=" + "$value" + "&");
});
String paramStr = sb.toString();
paramStr = paramStr.substring(0, paramStr.length - 1);
url += paramStr;
}
http.Response res = await http.get(url, headers: getCommonHeader());
return res.body;
}
第四步:POST方式请求
// post请求
static Future<String> post(String url, {Map<String, String> params}) async {
http.Response res = await http.post(url, body: params, headers: getCommonHeader());
print(res.statusCode);
return res.body;
}
其他请求方式与post方式类似,这儿就不一一列举其他请求方式了。
第五步:统一传参处理
static Map<String, String> getCommonHeader() {
Map<String, String> header = Map();
header['yingqi'] = "jackson影琪";
return header;
}
第六步:完整代码
import 'dart:async';
import 'package:http/http.dart' as http; class NetUtils {
// get请求的封装,传入的两个参数分别是请求URL和请求参数,请求参数以map的形式传入,会在方法体中自动拼接到URL后面
static Future<String> get(String url, {Map<String, String> params}) async {
if (params != null && params.isNotEmpty) {
// 如果参数不为空,则将参数拼接到URL后面
StringBuffer sb = StringBuffer("?");
params.forEach((key, value) {
sb.write("$key" + "=" + "$value" + "&");
});
String paramStr = sb.toString();
paramStr = paramStr.substring(0, paramStr.length - 1);
url += paramStr;
}
http.Response res = await http.get(url, headers: getCommonHeader());
return res.body;
} // post请求
static Future<String> post(String url, {Map<String, String> params}) async {
http.Response res = await http.post(url, body: params, headers: getCommonHeader());
print(res.statusCode);
return res.body;
} // put请求
static Future<String> put(String url, {Map<String, String> params}) async {
http.Response res = await http.put(url, body: params, headers: getCommonHeader());
return res.body;
} static Map<String, String> getCommonHeader() {
Map<String, String> header = Map();
header['yingqi'] = "1";
return header;
} }
2.2,Dio
第二步:引入包并创建网络请求类
import 'dart:async';
import 'package:dio/dio.dart'; class DioNetUtils { ... }
第三步:初始化Dio
static final DioNetUtils _singleton = DioNetUtils._init();
static Dio _dio; DioNetUtils._init() {
BaseOptions options = new BaseOptions(
baseUrl: "http://192.168.1.19:8880",
connectTimeout: 1000 * 1,
receiveTimeout: 1000 * 2,
//Http请求头.
headers: {//可统一配置传参
//do something
"version": "1.0.0"
},
//请求的Content-Type,默认值是"application/json; charset=utf-8". 也可以用"application/x-www-form-urlencoded"
// contentType: "application/json; charset=utf-8",
//表示期望以那种格式(方式)接受响应数据。接受4种类型 `json`, `stream`, `plain`, `bytes`. 默认值是 `json`,
responseType: ResponseType.json,
);
_dio = Dio(options); }
第四步:添加拦截器
//添加拦截器
_dio.interceptors
.add(InterceptorsWrapper(onRequest: (RequestOptions options) {
print("请求之前处理");
return options; //continue
}, onResponse: (Response response) {
print("响应之前处理");
print(options);
return response; // continue
}, onError: (DioError e) {
print("错误之前提示");
Response errorInfo = _dealErrorInfo(e);
return errorInfo; //continue
}));
第五步:统一处理错误信息
_dealErrorInfo(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;
}
第六步:GET方式请求
/// 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> request<T>(
String path, {
String method = Method.get,
String contentType= "application/json; charset=utf-8",
queryParameters,
Options options,
// CancelToken cancelToken,
}) async {
print('path===' + path);
Response response = await _dio.request(
path,
queryParameters: queryParameters,
options: _checkOptions(method, contentType, options),
// cancelToken: cancelToken,
);
_printHttpLog(response);
if (response.statusCode == 200) {
try {
if (response.data is Map) {
if (response.data["httpCode"] != 200) {
ShowToast.warning(response.data["message"]);
return new Future.error(new DioError(
response: response,
type: DioErrorType.RESPONSE,
));
}
// 由于不同的接口返回的格式不固定不规范,所以需要根据接口格式自定义.
return response.data['data'];
} else {
if (response.data is List) {
Map<String, dynamic> _dataMap = Map();
_dataMap["data"] = response.data;
return _dataMap;
}
}
} catch (e) {
ShowToast.warning("网络连接不可用,请稍后重试");
return new Future.error(new DioError(
response: response,
// message: "data parsing exception...",
type: DioErrorType.RESPONSE,
));
}
}
ShowToast.warning("网络连接不可用,请稍后重试");
return new Future.error(new DioError(
response: response,
type: DioErrorType.RESPONSE,
));
}
第七步:POST方式请求-json传值
/// 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> request<T>(
String path, {
String method = Method.get,
String contentType= "application/json; charset=utf-8",
queryParameters,
Options options,
// CancelToken cancelToken,
}) async {
print('path===' + path);
Response response;
if (method == Method.get) {
//GET方式 ... } else {
//除GET的其他方式
var requestData = queryParameters;
response = await _dio.request(
path,
data: requestData,
options: _checkOptions(method, contentType, options),
// cancelToken: cancelToken,
);
} _printHttpLog(response);
if (response.statusCode == 200) { ... } ... }
第八步:POST方式请求-表单传值
//if (contentType == 'application/x-www-form-urlencoded') {//表单方式
var requestData = new FormData.fromMap({
"name": "jackson影琪",
"age": 25,
});
第九步:请求日志处理
// print Http Log.
void _printHttpLog(Response response) {
print(!_isDebug);
if (!_isDebug) {
return;
}
try {
print("----------------Http Log Start----------------" +
_getOptionsStr(response.request));
print(response);
print("----------------Http Log end----------------");
} catch (ex) {
print("Http Log" + " error......");
}
} // get Options Str.
String _getOptionsStr(RequestOptions request) {
return "method: " +
request.method +
" baseUrl: " +
request.baseUrl +
" path: " +
request.path;
}
第10步:完整代码
import 'dart:async';
import 'package:dio/dio.dart';
import 'ShowToastUtils.dart'; class DioNetUtils {
static final DioNetUtils _singleton = DioNetUtils._init();
static Dio _dio; /// 是否是debug模式.
static bool _isDebug = true; /// 打开debug模式.
static void openDebug() {
_isDebug = true;
} DioNetUtils._init() {
BaseOptions options = new BaseOptions(
baseUrl: "http://192.168.1.19:8880",
connectTimeout: 1000 * 1,
receiveTimeout: 1000 * 2,
//Http请求头.
headers: {
//do something
"version": "1.0.0"
},
//请求的Content-Type,默认值是"application/json; charset=utf-8". 也可以用"application/x-www-form-urlencoded"
// contentType: "application/json; charset=utf-8",
//表示期望以那种格式(方式)接受响应数据。接受4种类型 `json`, `stream`, `plain`, `bytes`. 默认值是 `json`,
responseType: ResponseType.json,
);
_dio = Dio(options);
//添加拦截器
_dio.interceptors
.add(InterceptorsWrapper(onRequest: (RequestOptions options) {
print("请求之前处理");
return options; //continue
}, onResponse: (Response response) {
print("响应之前处理");
print(options);
return response; // continue
}, onError: (DioError e) {
print("错误之前提示");
Response errorInfo = _dealErrorInfo(e);
return errorInfo; //continue
}));
} 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> request<T>(
String path, {
String method = Method.get,
String contentType= "application/json; charset=utf-8",
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 == 'application/x-www-form-urlencoded') {//表单方式
requestData = new FormData.fromMap({
"name": "jackson影琪",
"age": 25,
});
}else{//json格式
requestData = queryParameters;
}
response = await _dio.request(
path,
data: requestData,
options: _checkOptions(method, contentType, options),
// cancelToken: cancelToken,
);
} _printHttpLog(response);
if (response.statusCode == 200) {
try {
if (response.data is Map) {
if (response.data["httpCode"] != 200) {
ShowToast.warning(response.data["message"]);
return new Future.error(new DioError(
response: response,
type: DioErrorType.RESPONSE,
));
}
// 由于不同的接口返回的格式不固定不规范,所以需要根据接口格式自定义.
return response.data['data'];
} else {
if (response.data is List) {
Map<String, dynamic> _dataMap = Map();
_dataMap["data"] = response.data;
return _dataMap;
}
}
} catch (e) {
ShowToast.warning("网络连接不可用,请稍后重试");
return new Future.error(new DioError(
response: response,
// message: "data parsing exception...",
type: DioErrorType.RESPONSE,
));
}
}
ShowToast.warning("网络连接不可用,请稍后重试");
return 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("----------------Http Log Start----------------" +
_getOptionsStr(response.request));
print(response);
print("----------------Http Log end----------------");
} catch (ex) {
print("Http Log" + " error......");
}
} // get Options Str.
String _getOptionsStr(RequestOptions request) {
return "method: " +
request.method +
" baseUrl: " +
request.baseUrl +
" path: " +
request.path;
} // 错误全局处理
_dealErrorInfo(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;
}
} abstract class DioCallback<T> {
void onSuccess(T t); void onError(DioError error);
}
** dio网络请求失败的回调错误码 **
/*
* 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;
}
** dio网络请求方式 **
/// 请求方法.
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";
}
三,接口调用
3.1,http请求库
1,页面调用
Map<String, String> params = Map();
params['loginCode'] = _unameController.text;
params['password'] = _pwdController.text;
NetUtils.post(ServiceApi.loginAction, params: params).then((data) {
print(ServiceApi.loginAction);
print(data);
}).catchError((e) {
Toast.toast(
context,
msg: '网络请求出错:$e,请稍后重试!',
position: 'top',
bgColor: Color.fromRGBO(130, 0, 0, 1), // Color 提示框背景颜色
textColor: Color.fromRGBO(250, 100, 100, 1), // Color 提示框文字颜色
);
});
3.2,Dio
1,服务接口地址
import 'dart:async';
import '../util/DioNetUtils.dart';
class ServiceNetApi {
///获取用户信息
Future<Map> getSingleDataById(data) async {
return await DioNetUtils().request<String>(
"/**/**/yingqi/**/getSingleDataById",
queryParameters: data,
method:Method.put
);
}
}
2,页面调用
void getData() async {
Map<String, String> params = Map();
params['Id'] = "123456789";
params['Name'] = "jackson影琪";
await ServiceNetApi().getSingleDataById(params).then((json) {
print('getSingleDataById');
print(json);
}).catchError((e) {
});
}
3,返回的结果

下一章->待定
Flutter之网络请求的更多相关文章
- flutter dio网络请求封装实现
flutter dio网络请求封装实现 文章友情链接: https://juejin.im/post/6844904098643312648 在Flutter项目中使用网络请求的方式大致可分为两种 ...
- 【技术博客】Flutter—使用网络请求的页面搭建流程、State生命周期、一些组件的应用
Flutter-使用网络请求的页面搭建流程.State生命周期.一些组件的应用 使用网络请求的页面搭建流程 在开发APP时,我们常常会遇到如下场景:进入一个页面后,要先进行网络调用,然后使用调用返 ...
- Flutter -------- dio网络请求
dio是Flutter中文网开源的一个强大的Dart Http请求库,支持Restful API.FormData.拦截器.请求取消.Cookie管理.文件上传/下载.超时等... 1.添加依赖# d ...
- Flutter网络请求和数据解析
一:前言 - 什么是反射机制,Flutter为什么禁用反射机制? 在Flutter中它的网络请求和数据解析稍微的比较麻烦一点,因为Flutter不支持反射机制.相信大家都看到这么一条,就是Flutte ...
- 从零学习Fluter(五):Flutter中手势滑动拖动已经网络请求
从六号开始搞Flutter,到今天写这篇blog已经过了4天时间,文档初步浏览了一遍,写下了这个demo.demo源码分享在github上,现在对flutter有种说不出的喜欢了.大家一起搞吧! 废话 ...
- Flutter 网络请求库http
http 集成http库 https://pub.dartlang.org/packages/http 添加依赖 dependencies: http: ^ 安装 flutter packages g ...
- Flutter网络请求与JSON解析
本文介绍如何在Flutter中创建HTTP网络请求和对请求的json string进行类型解析. 网络请求 官方使用的是用dart io中的HttpClient发起的请求,但HttpClient本身功 ...
- Flutter -------- Http库 网络请求封装(HttpController)
http库 再次封装的网络请求类 HttpController 1.添加依赖 dependencies: http: ^0.12.0 #latest version 2.导入库 import 'pac ...
- Flutter -------- 网络请求之HttpClient
今天来说说Flutter中的网络请求,HttpClient网络请求,包含get,post get var data; _get() async { Map newTitle; var response ...
随机推荐
- c#语法复习总结(1)-浅谈c#.net
出来工作两年,发现自己进步太小了,工作能力是不能混的,想先从基础知识好好复习一下,再深入的学习一些高级框架和先进的理念.找回了博客园的密码账号,好好学习和总结.先从数据类型总结一下,无非就是值类型,引 ...
- 聊聊Golang逃逸分析
逃逸分析的概念,go怎么开启逃逸分析的log. 以下资料来自互联网,有错误之处,请一定告之. 什么是逃逸分析 wiki上的定义 在编译程序优化理论中,逃逸分析是一种确定指针动态范围的方法——分析在程序 ...
- BZOJ1040: [ZJOI2008]骑士(奇环树,DP)
题目: 1040: [ZJOI2008]骑士 解析: 假设骑士\(u\)讨厌骑士\(v\),我们在\(u\),\(v\)之间连一条边,这样我们就得到了一个奇环树(奇环森林),既然是一颗奇环树,我们就先 ...
- spark和深度学习集成调研
http://dy.163.com/v2/article/detail/E2TMAOTU0518KCLV.html http://www.elecfans.com/d/676451.html http ...
- JavaWeb第二天--CSS
CSS CSS简述 CSS是什么?有什么作用? CSS(Cascading Style Sheets):层叠样式表. CSS通常称为CSS样式或层叠样式表.主要用于设置HTML页面中的文本内容(字体. ...
- jQuery源码学习一: 创建一个jquery实例
前言: jquery是每个前端都会的基础技能,众所周知,jquery返回的是jquery实例方法,但是我们似乎是直接使用$就可以获取到jquery的方法啦,可以在浏览器中判断一下 window.$ 和 ...
- JavaScript 之 定时器
JavaScript 里面有两个定时器:setTimeout() 和 setInterval() . 区别: setTimeout():相当于一个定时炸弹,隔一段时间执行,并且只会执行一次就不在执行了 ...
- CSS3实现0.5px边框
用CSS设置边框宽度为0.5px,可以使边框看起来更加细腻,特别是在移动端,设计师会有这样的要求. 但遗憾的是,大多数Android手机并不能识别0.5px.因此我们可以使用CSS3来变通的实现0.5 ...
- linux解压缩的常用命令
1.解包:tar xvf filename.tar, 打包: tar cvf filename DirName 2.解压:gunzip filename.gz, tar zxvf filename.t ...
- 【转】STM32利用FATFS读写数组
因为存为TXT可以实现,但是读取TXT里边的数据总是不尽如人意,所以,最终存为bin文件了. 先摘几个观点: http://www.openedv.com/posts/list/36712.htm “ ...