Flutter 网络请求框架封装,android 源码设计模式解析与实战
Dio dio = new Dio();var response = await dio.get("/test?id=12&name=chen");_content = response.data.toString();}
对于 query 参数,我们可以通过对象来进行传递,上面的代码等同于:
void getRequest() async {Dio dio = new Dio();var response = await dio.get("/test",data:{"id":12,"name":"chen"});_content = response.data.toString();}
Post 请求
void postRequest() async {var dio = new Dio();var response = await dio.post(url_post, data:{"id":12,"name":"wendu"});_content = response.data.toString();}
Dio 网络请求框架封装
日志信息拦截
Dio 和 okhttp 一样,都会有一个请求拦截器和响应拦截器,通过拦截器,我们可以在请求之前或响应之后做一些同意的预处理。例如我们发起请求前查看我们请求的参数和头部,响应的时候,我们可以查看返回来的数据。
Dio dio = new Dio();// 添加拦截器 if (Config.DEBUG) {dio.interceptors.add(InterceptorsWrapper(onRequest: (RequestOptions options){print("\n================== 请求数据 ==========================");print("url = {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.stackTrace}");print("\n");}));}
如果我们想要移除拦截器,那么我们可以将其设置为 null
dio.interceptor.request.onSend=null;dio.interceptor.response.onSuccess=null;dio.interceptor.response.onError=null;
token 添加
// 头部添加 token 验证 headers["Authorization"] = "token lskjdlklsjkdklsjd333";option.headers = headers;///超时 option.connectTimeout = 15000;try {Response response = await dio.request(url, data: params, options: option);} on DioError catch (e) {// 请求错误处理}
自动生成 dart 的 json 实体类插件 FlutterJsonBeanFactory
在 Android 开发中,有 GsonFormat 这个插件来讲 json 数据自动转化成 Bean;那么在 Flutter 中也有类似的插件可以生产序列化的实体类的插件:FlutterJsonBeanFactory
step 1:下载插件 FlutterJsonBeanFactory,安装完成后重启
Setting -> Plugins -> Browse Respositories 中搜索 FlutterJsonBeanFactory
step 2:创建实体类,在指定目录下:
New -> dart bean class File from JSON
step 3:输入实体类名及 json 格式的数据
step 4:最后生成的实体类:LoginEntity
class LoginEntity {String easemobpassword;String username;
LoginEntity({this.easemobpassword, this.username});
LoginEntity.fromJson(Map<String, dynamic> json) {easemobpassword = json['easemobPassword'];username = json['username'];}
Map<String, dynamic> toJson() {final Map<String, dynamic> data = new Map<String, dynamic>();data['easemobPassword'] = this.easemobpassword;data['username'] = this.username;return data;}}
请求错误处理
Response response;try {response = await dio.request(url, data: params, options: option);} on DioError catch (e) {// 请求错误处理 Response errorResponse;if (e.response != null) {errorResponse = e.response;} else {errorResponse = new Response(statusCode: 666);}if (e.type == DioErrorType.CONNECT_TIMEOUT) {errorResponse.statusCode = Code.NETWORK_TIMEOUT;}if (Config.DEBUG) {print('请求异常: ' + e.toString());print('请求异常 url: ' + url);}return new ResultData(Code.errorHandleFunction(errorResponse.statusCode, e.message, noTip), false, errorResponse.statusCode);}
其中 ResultData 是网络结果处理的实体类
/**
网络结果数据
Created by chenjianrun
Date: 2018-07-16*/class ResultData {var data;bool result;int code;var headers;
ResultData(this.data, this.result, this.code, {this.headers});}
Code 是
处理网络错误的编码,并将错误结果通过 eventbus 发送出去,一般我们可以在 main_pager 中注册监听这个事件。
///网络请求错误编码 class Code {///网络错误 static const NETWORK_ERROR = -1;
///网络超时 static const NETWORK_TIMEOUT = -2;
///网络返回数据格式化一次 static const NETWORK_JSON_EXCEPTION = -3;
static const SUCCESS = 200;
static final EventBus eventBus = new EventBus();
static errorHandleFunction(code, message, noTip) {if(noTip) {return message;}eventBus.fire(new HttpErrorEvent(code, message));return message;}}
完成的网络请求类:HttpRequest
import 'dart:io';
import 'package:dio/dio.dart';import 'package:private_tutor/common/SpUtils.dart';import 'package:connectivity/connectivity.dart';
import 'dart:collection';
import 'package:private_tutor/common/config/Config.dart';import 'package:private_tutor/net/ResultCode.dart';import 'package:private_tutor/net/ResultData.dart';
///http 请求管理类,可单独抽取出来 class HttpRequest {static String _baseUrl;static const CONTENT_TYPE_JSON = "application/json";static const CONTENT_TYPE_FORM = "application/x-www-form-urlencoded";static Map optionParams = {"timeoutMs": 15000,"token": null,"authorizationCode": null,};
static setBaseUrl(String baseUrl){_baseUrl = baseUrl;}
static get(url,param) async{return await request(_baseUrl+url, param, null, new Options(method:"GET"));}
static post(url,param) async{return await request(_baseUrl+url, param, {"Accept": 'application/vnd.github.VERSION.full+json'}, new Options(method: 'POST'));}
static delete(url,param) async{return await request(_baseUrl+url, param, null, new Options(method: 'DELETE'));}
static put(url,param) async{return await request(_baseUrl+url, param, null, new Options(method: "PUT", contentType: ContentType.text));}
///发起网络请求///[ url] 请求 url///[ params] 请求参数///[ header] 外加头///[ option] 配置 static request(url, params, Map<String, String> header, Options option, {noTip = false}) async {
//没有网络 var connectivityResult = await (new Connectivity().checkConnectivity());if (connectivityResult == ConnectivityResult.none) {return new ResultData(Code.errorHandleFunction(Code.NETWORK_ERROR, "", noTip), false, Code.NETWORK_ERROR);}
Map<String, String> headers = new HashMap();if (header != null) {headers.addAll(header);}
//授权码 if (optionParams["authorizationCode"] == null) {var authorizationCode = await getAuthorization();if (authorizationCode != null) {optionParams["authorizationCode"] = authorizationCode;}}
headers["Authorization"] = optionParams["authorizationCode"];// 设置 baseUrl
if (option != null) {option.headers = headers;} else{option = new Options(method: "get");option.headers = headers;}
///超时 option.connectTimeout = 15000;
Dio dio = new Dio();// 添加拦截器 if (Config.DEBUG) {dio.interceptors.add(InterceptorsWrapper(onRequest: (RequestOptions options){print("\n================== 请求数据 ==========================");print("url = {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.stackTrace}");print("\n");}));}
Response response;try {response = await dio.request(url, data: params, options: option);} on DioError catch (e) {// 请求错误处理 Response errorResponse;if (e.response != null) {errorResponse = e.response;} else {errorResponse = new Response(statusCode: 666);}if (e.type == DioErrorType.CONNECT_TIMEOUT) {errorResponse.statusCode = Code.NETWORK_TIMEOUT;}if (Config.DEBUG) {print('请求异常: ' + e.toString());print('请求异常 url: ' + url);}
评论