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 ...
随机推荐
- 前端开发常用 JS 方法
1,获取文件本地url,在上传之前预览 /** * 获取图片嗯滴url,在上传之前预览 * @param file 选择的图片文件 * @returns {*} url */ getFileLocat ...
- SpringMVC+EasyUI实现页面左侧导航菜单
1. 效果图展示 2. 工程目录结构 注意: webapp下的resources目录放置easyui和js(jQuery文件是另外的) 3. 代码 index.j ...
- jQuery---bootstrap的下载使用,栅格(12个格子),轮播图,矢量图字体图标,进度条,选项卡,标签,表达校验
jQuery---bootstrap的下载使用,栅格(12个格子),轮播图,矢量图字体图标,进度条,选项卡,标签,表达校验 一丶bootstrap的使用 下载资源文件: bootstrap官网 导入 ...
- OpenGL 中的三维纹理操作
#define _CRT_SECURE_NO_WARNINGS #include <gl/glut.h> #include <stdio.h> #include <std ...
- 15、vue项目封装axios并访问接口
1.在src下新建util文件夹,在util下新建request.js文件: 封装axios: import axios from 'axios' import QS from 'qs'; // im ...
- jmeter-Unable to access jarfile ApacheJMeter.jar
jmeter在运行时报错Unable to access jarfile ApacheJMeter.jar.如下图: 检查后发现jmeter_home/bin/目录下缺失 ApacheJMeter.j ...
- pandas 之 group by 过程
import numpy as np import pandas as pd Categorizing a dataset and applying a function to each group ...
- window10体验terminal
体验window-terminal(preview),很不错可以直接登录服务器通过ssh 01.打开store 02.搜索terminal 03.体验ssh主机 04.很爽,可以ctrl + 鼠标滚轮 ...
- CC2530 light_switch分析
一些关键字: CCM - Counter with CBC-MAC (mode ofoperation) HAL - HardwareAbstraction Layer (硬件抽象层) ...
- Django之DRF源码分析(四)---频率认证组件
核心源码 def check_throttles(self, request): """ Check if request should be throttled. Ra ...