注册

跟我学企业级flutter项目:dio网络框架增加公共请求参数&header

前言

跟我学flutter系列:
跟我学flutter:我们来举个例子通俗易懂讲解dart 中的 mixin
跟我学flutter:我们来举个例子通俗易懂讲解异步(一)ioslate
跟我学flutter:我们来举个例子通俗易懂讲解异步(二)ioslate循环机制
企业级篇目:
跟我学企业级flutter项目:用bloc手把手教你搭建用户认证系统
跟我学企业级flutter项目:dio网络框架增加公共请求参数&header
跟我学企业级flutter项目:如何用dio封装一套企业级可扩展高效的网络层
跟我学企业级flutter项目:如何封装一套易用,可扩展的Hybrid混合开发webview
跟我学企业级flutter项目:手把手教你制作一款低耦合空页面widget

在开发过程中,我们经常会用到网络请求,在flutter框架中,dio框架非常不错,所以今天的文章在dio的基础上搭建一套网络持久化框架,那么在flutter项目中如何搭建一套,高可用性,维护性较高的dio公共请求参数框架呢?

搭建前夕准备

一、基本认知

  1. 要持久化那么必然要有存储设备
  2. 持久化的数据在app启动后要即使填充到项目中
  3. 由于项目中网络请求地址繁多,类型不同,需要持久化的位置不同

二、基于基本认知来找合适的工具&必要点

2.1 持久化的工具:

我的推荐

  1. mmkv
  2. share_prefresence

今天主要用讲解mmkv版本

2.2必要点:

dio拦截器

拦截器是搭建这套持久化的关键

三、准备好如上技能,我们来搭建这套持久化网络框架吧

1、首先要知道有几种类型的公共

  //请求中url后追加公共请求
static const int urlPresistent = 1;
//请求头中追加公共请求
static const int headerPresistent = 2;
//全部都追加公共请求
static const int allPresistent = 3;

2、构建缓存参数(为了快速获取)

  static Map> headerPersistent = Map();
static Map> urlPersistent = Map();
,map,map

3、构建mmkv存储结构(加密存储)

static MMKV _store(String baseUrl, int type) => MMKVStore.sysSafeMMKV(name: '${SysConfig.sysPersistent}${baseUrl}_${type.toString()}');

4、构建基本函数

单健值对存储

static void setPersistent(String baseUrl,String key,String? value,{int type = allPresistent}){
if (type == allPresistent || type == headerPresistent) {
if (!headerPersistent.containsKey(baseUrl)) {
headerPersistent[baseUrl] = Map();
}
var keyMap = headerPersistent[baseUrl]!;
keyMap[key] = value;
_store(baseUrl, headerPresistent).encodeString(key, value??"");
}
if (type == allPresistent || type == urlPresistent) {
if (!urlPersistent.containsKey(baseUrl)) {
urlPersistent[baseUrl] = Map();
}
var keyMap = urlPersistent[baseUrl]!;
keyMap[key] = value;
_store(baseUrl, urlPresistent).encodeString(key, value??"");
}
}
,>,>

多健值对存储

static void setPersistentMap(String baseUrl,Mapmap,{int type = allPresistent}){
if (type == allPresistent || type == headerPresistent) {
if (!headerPersistent.containsKey(baseUrl)) {
headerPersistent[baseUrl] = Map();
}
var keyMap = headerPersistent[baseUrl]!;
keyMap.addAll(map);
keyMap.forEach((key, value) {
_store(baseUrl, headerPresistent).encodeString(key, value??"");
});
}
if (type == allPresistent || type == urlPresistent) {
if (!urlPersistent.containsKey(baseUrl)) {
urlPersistent[baseUrl] = Map();
}
var keyMap = urlPersistent[baseUrl]!;
keyMap.addAll(map);
keyMap.forEach((key, value) {
_store(baseUrl, urlPresistent).encodeString(key, value??"");
});
}
}
,>,>,>

参数获取:

  static Map? getPersistent(String baseUrl, {int type = allPresistent}) {
Map? map;
if (type == allPresistent || type == headerPresistent) {
Map? headerMap;
if (headerPersistent.containsKey(baseUrl)) {
headerMap = headerPersistent[baseUrl];
} else {
headerMap = null;
}
if (headerMap != null) {
if (map == null) {
map = Map();
}
map.addAll(headerMap);
}
}
if (type == allPresistent || type == urlPresistent) {
Map? urlMap;
if (urlPersistent.containsKey(baseUrl)) {
urlMap = urlPersistent[baseUrl];
} else {
urlMap = null;
}

if (urlMap != null) {
if (map == null) {
map = Map();
}
map.addAll(urlMap);
}
}
return map;
}
,>,>,>,>

刷新当前缓存(应用启动刷新)

  static Map _all(String baseurl, int type) {
var mmkv= _store(baseurl, type);
var keys = mmkv.allKeys;
var map = Map();
keys.forEach((element) {
var value = mmkv.decodeString(element);
map[element] = value;
});
return map;
}

static void flushPersistent(String baseurl, {int type = allPresistent}) {
if (type == allPresistent || type == headerPresistent) {
var map = _all(baseurl, headerPresistent);
headerPersistent[baseurl]?.clear();

if (!headerPersistent.containsKey(baseurl)) {
headerPersistent[baseurl] = Map();
}
var keyMap = headerPersistent[baseurl]!;
keyMap.addAll(map);
}
if (type == allPresistent || type == urlPresistent) {
var map = _all(baseurl, urlPresistent);
urlPersistent[baseurl]?.clear();
if (!urlPersistent.containsKey(baseurl)) {
urlPersistent[baseurl] = Map();
}
var keyMap = urlPersistent[baseurl]!;
keyMap.addAll(map);
}

}
,>,>,>,>

退出登陆移除持久化

static void removeAllPersistent(String baseurl, {int type = allPresistent}) {
if (type == allPresistent || type == headerPresistent) {
headerPersistent[baseurl]?.clear();
_store(baseurl, headerPresistent).clearAll();
}
if (type == allPresistent || type == urlPresistent) {
urlPersistent[baseurl]?.clear();
_store(baseurl, urlPresistent).clearAll();
}
}

拦截器实现(dio请求拦截管理)

class PresistentInterceptor extends Interceptor {

@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler)
{
var urlPersitents = HttpPersistent.getPersistent(options.baseUrl,type: HttpPersistent.urlPresistent);
var headerPersitents = HttpPersistent.getPersistent(options.baseUrl,
type: HttpPersistent.headerPresistent);
headerPersitents?.forEach((key, value) {
options.headers[key] = value;
});

urlPersitents?.forEach((key, value) {
options.queryParameters[key] = value;
});
super.onRequest(options, handler);
}

}

四、整体代码&事件调用逻辑

整体代码


class HttpPersistent{

static const int urlPresistent = 1;
static const int headerPresistent = 2;
static const int allPresistent = 3;

static MMKV _store(String baseUrl, int type) => MMKVStore.sysSafeMMKV(name: '${SysConfig.sysPersistent}${baseUrl}_${type.toString()}');
static Map> headerPersistent = Map();
static Map> urlPersistent = Map();

static void setPersistent(String baseUrl,String key,String? value,{int type = allPresistent}){
if (type == allPresistent || type == headerPresistent) {
if (!headerPersistent.containsKey(baseUrl)) {
headerPersistent[baseUrl] = Map();
}
var keyMap = headerPersistent[baseUrl]!;
keyMap[key] = value;
_store(baseUrl, headerPresistent).encodeString(key, value??"");
}
if (type == allPresistent || type == urlPresistent) {
if (!urlPersistent.containsKey(baseUrl)) {
urlPersistent[baseUrl] = Map();
}
var keyMap = urlPersistent[baseUrl]!;
keyMap[key] = value;
_store(baseUrl, urlPresistent).encodeString(key, value??"");
}
}

static void setPersistentMap(String baseUrl,Map map,{int type = allPresistent}){
if (type == allPresistent || type == headerPresistent) {
if (!headerPersistent.containsKey(baseUrl)) {
headerPersistent[baseUrl] = Map();
}
var keyMap = headerPersistent[baseUrl]!;
keyMap.addAll(map);
keyMap.forEach((key, value) {
_store(baseUrl, headerPresistent).encodeString(key, value??"");
});
}
if (type == allPresistent || type == urlPresistent) {
if (!urlPersistent.containsKey(baseUrl)) {
urlPersistent[baseUrl] = Map();
}
var keyMap = urlPersistent[baseUrl]!;
keyMap.addAll(map);
keyMap.forEach((key, value) {
_store(baseUrl, urlPresistent).encodeString(key, value??"");
});
}
}

static Map? getPersistent(String baseUrl, {int type = allPresistent}) {
Map? map;
if (type == allPresistent || type == headerPresistent) {
Map? headerMap;
if (headerPersistent.containsKey(baseUrl)) {
headerMap = headerPersistent[baseUrl];
} else {
headerMap = null;
}
if (headerMap != null) {
if (map == null) {
map = Map();
}
map.addAll(headerMap);
}
}
if (type == allPresistent || type == urlPresistent) {
Map? urlMap;
if (urlPersistent.containsKey(baseUrl)) {
urlMap = urlPersistent[baseUrl];
} else {
urlMap = null;
}

if (urlMap != null) {
if (map == null) {
map = Map();
}
map.addAll(urlMap);
}
}
return map;
}

static Map _all(String baseurl, int type) {
var mmkv= _store(baseurl, type);
var keys = mmkv.allKeys;
var map = Map();
keys.forEach((element) {
var value = mmkv.decodeString(element);
map[element] = value;
});
return map;
}

static void flushPersistent(String baseurl, {int type = allPresistent}) {
if (type == allPresistent || type == headerPresistent) {
var map = _all(baseurl, headerPresistent);
headerPersistent[baseurl]?.clear();

if (!headerPersistent.containsKey(baseurl)) {
headerPersistent[baseurl] = Map();
}
var keyMap = headerPersistent[baseurl]!;
keyMap.addAll(map);
}
if (type == allPresistent || type == urlPresistent) {
var map = _all(baseurl, urlPresistent);
urlPersistent[baseurl]?.clear();
if (!urlPersistent.containsKey(baseurl)) {
urlPersistent[baseurl] = Map();
}
var keyMap = urlPersistent[baseurl]!;
keyMap.addAll(map);
}

}

static void removeAllPersistent(String baseurl, {int type = allPresistent}) {
if (type == allPresistent || type == headerPresistent) {
headerPersistent[baseurl]?.clear();
_store(baseurl, headerPresistent).clearAll();
}
if (type == allPresistent || type == urlPresistent) {
urlPersistent[baseurl]?.clear();
_store(baseurl, urlPresistent).clearAll();
}
}
}



class PresistentInterceptor extends Interceptor {

@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
var urlPersitents = HttpPersistent.getPersistent(options.baseUrl,type: HttpPersistent.urlPresistent);
var headerPersitents = HttpPersistent.getPersistent(options.baseUrl,
type: HttpPersistent.headerPresistent);
headerPersitents?.forEach((key, value) {
options.headers[key] = value;
});

urlPersitents?.forEach((key, value) {
options.queryParameters[key] = value;
});
super.onRequest(options, handler);
}

}
,>,>,>,>,>,>,>,>,>,>,>,>,>,map,map

1、登陆后,调用存储 HttpPersistent.setPersistent("http://www.baidu.com","token","123",HttpPersistent.headerPresistent)

 2、退出登陆后,调用移除 HttpPersistent.removeAllPersistent("http://www.baidu.com",,type: HttpPersistent.headerPresistent); 

3、应用启动后刷新缓存
HttpPersistent.flushPersistent("http://www.baidu.com", type: HttpPersistent.headerPresistent);

五、大功告成

如上就构建出一套可靠性高,维护性高的网络持久化框架

更多flutter教程请关注我的IMGeek:http://www.imgeek.org/people/3369…


2 个评论

有个小疑问,如果服务器踢出这个token,页面怎么知道。
很简单,提出token一般来说,网络请求会返回指定token,那么对这个进行拦截处理(清理token)就行。

要回复文章请先登录注册