网络请求框架设计目标:
● 支持网络库插拔设计,不干扰业务层
● 简洁易用,支持配置来进行请求
● Adapter设计,可扩展性强
● 统一异常和返回处理
网络请求设计框架
1. 定义基础请求抽象类
enum HttpMethod { get, post, delete, put }
/// 基础请求
abstract class BaseRequest {
var pathParams;
var useHttpRequest = true;
// 域名
String authority() {
return "rlmqj.wiremockapi.cloud";
}
HttpMethod httpMethod();
String path();
String url() {
Uri uri;
var pathString = path();
// 拼接path参数
if (pathParams != null) {
if (path().endsWith('/')) {
pathString = '${path()}$pathParams';
} else {
pathString = '${path()}/$pathParams';
}
}
// http和https切换
if (useHttpRequest) {
uri = Uri.https(authority(), pathString, paramas);
} else {
uri = Uri.http(authority(), pathString, paramas);
}
print('url:${uri.toString()}');
return uri.toString();
}
bool needLogin();
// 参数
Map<String, String> paramas = Map();
/// 添加参数
BaseRequest add(String k, Object v) {
paramas[k] = v.toString();
return this;
}
/// header参数
Map<String, String> header = Map();
BaseRequest addHeader(String k, Object v) {
paramas[k] = v.toString();
return this;
}
}
2. 定义网络请求工厂方法
import 'package:flutter_application_1/NetworkKit/DioAdapter.dart';
import 'package:flutter_application_1/NetworkKit/NetError.dart';
import 'package:flutter_application_1/NetworkKit/NetworkAdaptor.dart';
import 'package:flutter_application_1/NetworkKit/request.dart';
class NetworkProvider {
// 私有初始化
// 私有的命名构造函数
NetworkProvider._internal();
// 使用 late 关键字实现懒加载并确保 null 安全
static final NetworkProvider _instance = NetworkProvider._internal();
// 提供一个工厂构造函数来返回唯一的实例
factory NetworkProvider() {
return _instance;
}
// 请求方法
Future fire(BaseRequest request) async {
NetResponse? response;
var error;
try {
response = await send(request);
} on NetError catch (e) {
error = e;
response = e.data;
printLog(e.message);
} catch (e) {
// 其他异常
error = e;
printLog(e);
}
if (response == null) {
printLog(error);
}
// var response = await send(request);
var result = response?.data;
var status = response?.statusCode;
switch (status) {
case 200:
printLog(result);
return result;
case 401:
throw NeedLogin();
case 403:
throw NeedAuth();
default:
throw Exception();
}
}
Future<dynamic> send<T>(BaseRequest request) async {
// print('url:${request.url()}');
// print('method:${request.httpMethod()}');
// request.addHeader('token', '123');
// print('header:${request.header}');
// 使用Mock发送数据
// Networkadaptor adapter = MockAdapter();
// return adapter.send(request);
// 使用Dio进行网络请求
Dioadapter adapter = Dioadapter();
return adapter.send(request);
}
void printLog(log) {
print('net: ${log.toString()}');
}
}
3. 定义网络请求返回数据格式,定义请求工厂抽象类
import 'dart:convert';
import 'package:flutter_application_1/NetworkKit/request.dart';
/// 同一网络层返回格式
class NetResponse {
NetResponse(
{this.data,
this.request,
this.statusCode,
this.statusMessage,
this.extra});
Map<String, dynamic>? data;
BaseRequest? request;
int? statusCode;
String? statusMessage;
Map<String, dynamic>? extra;
@override
String toString() {
if (data is Map) {
return json.encode(data);
}
return data.toString();
}
}
/// 网络请求Adapter类
abstract class Networkadaptor {
Future<NetResponse> send(BaseRequest request);
}
// 实现三方库Dio网络请求方法
import 'package:dio/dio.dart';
import 'package:flutter_application_1/NetworkKit/NetError.dart';
import 'package:flutter_application_1/NetworkKit/request.dart';
import 'NetworkAdaptor.dart';
class Dioadapter extends Networkadaptor {
@override
Future<NetResponse> send(BaseRequest request) async {
var response, options = Options(headers: request.header);
final dio = Dio();
var error;
try {
switch (request.httpMethod()) {
case HttpMethod.get:
response = await dio.get(request.url(), options: options);
break;
case HttpMethod.post:
response = await dio.post(request.url(),
data: request.paramas, options: options);
break;
case HttpMethod.delete:
response = await dio.delete(request.url(),
data: request.paramas, options: options);
break;
default:
}
} on DioException catch (e) {
error = e;
response = e.response;
}
if (error != null) {
/// 抛出NetError
throw NetError(response.statusCode, error.toString());
}
return buildRes(response, request);
}
NetResponse buildRes(Response response, BaseRequest request) {
// 确保 data 的类型是 Map<String, dynamic>
var data = response.data;
// 使用指定的泛型类型创建 NetResponse 对象
NetResponse myResponse = NetResponse(
data: data,
request: request,
statusCode: response.statusCode,
statusMessage: response.statusMessage,
);
return myResponse;
}
}