iis网站重定向,wordpress无插件主题,免费旅行社网站模板,深圳一医疗公司给员工放假10个月在移动APP开发过程中#xff0c;进行数据交互时#xff0c;大多数情况下必须通过网络请求来实现。客户端与服务端常用的数据交互是通过HTTP请求完成。面对繁琐业务网络层#xff0c;我们该如何通过网络层架构设计来有效解决这些问题#xff0c;这便是网络层框架架构设计的初…在移动APP开发过程中进行数据交互时大多数情况下必须通过网络请求来实现。客户端与服务端常用的数据交互是通过HTTP请求完成。面对繁琐业务网络层我们该如何通过网络层架构设计来有效解决这些问题这便是网络层框架架构设计的初衷。
设计要求
1. 支持网络库插拔设计且不干扰业务层
2. 简洁易用支持配置来进行请求
3. Adapter设计扩展性强
4. 统一异常和返回处理 解决问题
切换成本高网络操作使用的三方库存在不维护切换成本高的风险
接口管理不便对于大中型APP接口众多不方便管理
重复代码多APP中进行数据交互的场景很多网络请求存在大量的重复代码
扩展性差网络操作和业务代码耦合严重不利于扩展
开发效率低不同三方库使用方式不统一步骤繁琐开发效率低
一、搭建基础的网络请求框架HiNet
1创建基础请求
创建抽象的基础请求类BaseRequest并向上层提供获取请求路径请求方式等抽象方法及添加参数和请求头等能力。
base_request.dart
enum HttpMethod { GET, POST, DELETE }/// 基础请求
abstract class BaseRequest {var pathParams;var userHttps true;/// 域名String authority() {return api.devio.org;}HttpMethod httpMethod();String path();String url() {Uri uri;var pathStr path();// 拼接路径参数if (pathParams ! null) {if (pathStr.endsWith(/)) {pathStr $pathStr$pathParams;} else {pathStr $pathStr/$pathParams;}}// http和https的切换if (userHttps) {uri Uri.https(authority(), pathStr, params);} else {uri Uri.http(authority(), pathStr, params);}print(url:${uri.toString()});return uri.toString();}bool needLogin();MapString, String params {};/// 添加参数BaseRequest add(String k, Object v) {params[k] v.toString();return this;}MapString, dynamic header {};/// 添加请求头BaseRequest addHeader(String k, Object v) {header[k] v.toString();return this;}
}2创建测试请求
创建测试请求类TextRequest继承自 基础请求抽象类BaseRequest实现请求路径和请求方式等。
test_request.dart
import package:hi_net/http/request/base_request.dart;class TestRequest extends BaseRequest{overrideHttpMethod httpMethod() {return HttpMethod.GET;}overridebool needLogin() {return false;}overrideString path() {return uapi/test/test;}
}
3创建核心网络请求类
创建核心网络请求类HiNet提供发送请求接收响应解析返回数据统一错误处理等功能。当前使用模拟响应请求的方式下面内容会带着大家一步一步进行完善。
hi_net.dart
import package:hi_net/http/request/base_request.dart;class HiNet {HiNet._internal();static HiNet? _instance;static HiNet get getInstance {_instance ?? HiNet._internal();return _instance!;}Future fire(BaseRequest request) async {var respones await send(request);var result respones[data];print(result:$result);return result;}Futuredynamic sendT(BaseRequest request) {print(url:${request.url()});print(httpMethod:${request.httpMethod()});request.addHeader(aaaa, bbbb);print(header:${request.header});return Future.value({statusCode: 200,data: {code: 0, message: success}});}
}4发送测试请求
创建TestRequest测试请求对象使用HiNet网络请求核心单例类进行模拟Http请求。
TestRequest testRequest TestRequest();
testRequest.add(1111, 2222).add(3333, 4444);
HiNet.getInstance.fire(testRequest);
模拟接口请求成功输出log 二、增加统一异常和响应数据处理及Adapter模式设计
1创建网络异常统一格式类
创建网络异常统一格式类HiNetError包含code、message和data信息。
创建登录异常NeedLogin 和 授权异常NeedAuth 继承自HiNetError。
hi_net_error.dart
/// 需要登录的异常
class NeedLogin extends HiNetError {NeedLogin({int code 401, String message 请先登录}) : super(code, message);
}/// 需要授权的异常
class NeedAuth extends HiNetError {NeedAuth(String message, {int code 403, dynamic data}): super(code, message, data: data);
}/// 网络异常统一格式类
class HiNetError implements Exception {final int code;final String message;final dynamic data;HiNetError(this.code, this.message, {this.data});
}2创建统一网络层返回格式
创建统一网络层返回格式HiNetResponse包含request、statusCode、statusMessage和data等信息。
hi_net_adapter.dart
/// 统一网络层返回格式
class HiNetResponseT {HiNetResponse({this.data,this.request,this.statusCode,this.statusMessage,this.extra});T? data;BaseRequest? request;int? statusCode;String? statusMessage;dynamic extra;overrideString toString() {if (data is Map) {return json.encode(data);}return data.toString();}
}3创建网络请求抽象类
网络请求抽象类HiNetAdapter提供发送请求能力。
hi_net_adapter.dart
import dart:convert;import package:hi_net/http/request/base_request.dart;/// 网络请求抽象类
abstract class HiNetAdapter {FutureHiNetResponseT sendT(BaseRequest request);
}/// 统一网络层返回格式
class HiNetResponseT {HiNetResponse({this.data,this.request,this.statusCode,this.statusMessage,this.extra});T? data;BaseRequest? request;int? statusCode;String? statusMessage;dynamic extra;overrideString toString() {if (data is Map) {return json.encode(data);}return data.toString();}
}4创建测试适配器
创建测试适配器MockAdapter mock数据。
mock_adapter.dart
import package:hi_net/http/core/hi_net_adapter.dart;
import package:hi_net/http/request/base_request.dart;/// 测试适配器mock数据
class MockAdapter extends HiNetAdapter {overrideFutureHiNetResponseT sendT(BaseRequest request) {return Future.delayed(const Duration(milliseconds: 1000), () {return HiNetResponse(data: {code: 0, message: success} as T, statusCode: 200);});}
}5完善核心网络请求类
完善核心网络请求类HiNet使用mock适配器MockAdapter发送请求使用HiNetResponse接收请求响应数据增加统一错误处理。
hi_net.dart
import package:hi_net/http/core/hi_net_adapter.dart;
import package:hi_net/http/core/hi_net_error.dart;
import package:hi_net/http/core/mock_adapter.dart;
import package:hi_net/http/request/base_request.dart;class HiNet {HiNet._internal();static HiNet? _instance;static HiNet get getInstance {_instance ?? HiNet._internal();return _instance!;}Future fire(BaseRequest request) async {HiNetResponse? response;var error;try {response await send(request);} on HiNetError catch (e) {error e;response e.data;print(HiNetError:${e.message});} catch (e) {// 其他错误error e;print(OtherError:$e);}if (response null) {print(error:$error);}var result response?.data;print(result:$result);var status response?.statusCode ?? 0;switch (status) {case 200:return result;case 401:throw NeedLogin();case 403:throw NeedAuth(result.toString(), data: result);default:throw HiNetError(status, result.toString(), data: result);}}Futuredynamic sendT(BaseRequest request) {print(url:${request.url()});/// 使用mock发送请求HiNetAdapter adapter MockAdapter();return adapter.send(request);}
}6发送测试请求
创建TestRequest测试请求对象使用HiNet网络请求核心单例类进行模拟Http请求。 TestRequest testRequest TestRequest();testRequest.add(1111, 2222).add(3333, 4444);try{var result await HiNet.getInstance.fire(testRequest);print(result);} on NeedAuth catch (e) {print(e);} on NeedAuth catch (e) {print(e);} on HiNetError catch (e) {print(e);}
模拟接口请求成功输出log 三、 扩展hi_net添加对dio的支持
1创建dio适配器
创建dio适配器DioAdapter重写发送请求的send方法采用dio框架进行真正的Http网络请求根据服务器响应数据构建HiNetError 和 HiNetResponse。
添加dio依赖
pubspec.yaml
dio: ^5.7.0
dio_adapter.dart
import package:dio/dio.dart;
import package:hi_net/http/core/hi_net_adapter.dart;
import package:hi_net/http/core/hi_net_error.dart;
import package:hi_net/http/request/base_request.dart;/// Dio适配器
class DioAdapter extends HiNetAdapter {overrideFutureHiNetResponseT sendT(BaseRequest request) async {Response? response;var error, options Options(headers: request.header);try {if (request.httpMethod() HttpMethod.GET) {response await Dio().get(request.url(), options: options);} else if (request.httpMethod() HttpMethod.POST) {response await Dio().post(request.url(), data: request.params, options: options);} else if (request.httpMethod() HttpMethod.DELETE) {response await Dio().delete(request.url(), data: request.params, options: options);}} on DioError catch (e) {error e;response e.response;}if (error ! null) {/// 抛出HiNetError异常throw HiNetError(response?.statusCode ?? -1, error.toString(),data: buildResponse(response, request));}return buildResponse(response, request);}/// 构建HiNetResponseHiNetResponseT buildResponseT(Response? response, BaseRequest request) {return HiNetResponse(data: response?.data as T,request: request,statusCode: response?.statusCode,statusMessage: response?.statusMessage,extra: response);}
}2使用dio发送请求
修改HiNet 的send方法使用dio适配器发送请求Adapter设计可轻便的更换三方网络请求库加强了网络请求架构的扩展性。
hi_net.dart
import package:hi_net/http/core/hi_net_adapter.dart;
import package:hi_net/http/core/hi_net_error.dart;
import package:hi_net/http/core/adapter/mock_adapter.dart;
import package:hi_net/http/request/base_request.dart;import adapter/dio_adapter.dart;///1.支持网络库插拔设计且不干扰业务层
///2.基于配置请求请求简洁易用
///3.Adapter设计扩展性强
///4.统一异常和返回处理
class HiNet {Futuredynamic sendT(BaseRequest request) {print(url:${request.url()});/// 使用mock发送请求/// HiNetAdapter adapter MockAdapter();/// 使用dio发送请求HiNetAdapter adapter DioAdapter();return adapter.send(request);}
}3发送测试请求
创建TestRequest测试请求对象使用HiNet网络请求核心单例类进行Http请求。
注意该测试接口requestPrams是必传字段不传接口会返回失败。 TestRequest testRequest TestRequest();testRequest.add(1111, 2222).add(3333, 4444).add(requestPrams, 5555);try{var result await HiNet.getInstance.fire(testRequest);print(testRequest result: $result);} on NeedAuth catch (e) {print(e);} on NeedAuth catch (e) {print(e);} on HiNetError catch (e) {print(e);}
Http接口请求成功输出log Http接口请求失败输出log 四、JSON编码器和解码器
1使用 json_serializable 框架
使用 json_serializable 框架对JSON数据进行解析。
添加 json_serializable 依赖
pubspec.yaml json_serializable: ^6.8.0json_annotation: ^4.9.0build_runner: ^2.1.11
2创建测试接口返回数据bean
测试接口返回接送数据
{code: 0, method: GET, requestPrams: 5555}
创建TestModel编写好属性、构造方法、TestModel.fromJson() 和 toJson()增加注解JsonSerializable()
test_model.dart
import package:json_annotation/json_annotation.dart;part test_model.g.dart;/// 测试接口返回数据bean
/// {code: 0, method: GET, requestPrams: 5555}
JsonSerializable()
class TestModel {int code;String method;String requestPrams;TestModel(this.code, this.method, this.requestPrams);//固定格式不同的类使用不同的mixin即可factory TestModel.fromJson(MapString, dynamic json) _$TestModelFromJson(json);//固定格式MapString, dynamic toJson() _$TestModelToJson(this);
}执行 dart run build_runner build 提示需要在 TestModel 增加 part test_model.g.dart;
加上后再次执行 dart run build_runner build 接口自动生成 test_model.g.dart 文件 总结使用 json_serializable 框架构建JSON解析类时手动创建的基类ModelTestModel必须满足以下要求
1. 在Model类编写 part 同Model类文件名.g.dart; 如 TestModel类文件名est_model.dart 则编写 part test_model.g.dart;
2.增加注解 JsonSerializable()
3.编写固定格式的代码名字换成基类名字这里是TestModel //固定格式不同的类使用不同的mixin即可factory TestModel.fromJson(MapString, dynamic json) _$TestModelFromJson(json);//固定格式MapString, dynamic toJson() _$TestModelToJson(this);
3使用 TestRequest testRequest TestRequest();testRequest.add(1111, 2222).add(3333, 4444).add(requestPrams, 5555);try{var result await HiNet.getInstance.fire(testRequest);var testModel TestModel.fromJson(result[data]);print(testRequest requestPrams: ${testModel.requestPrams});} on NeedAuth catch (e) {print(e);} on NeedAuth catch (e) {print(e);} on HiNetError catch (e) {print(e);}
JSON解析输出log 至此完成了网络请求框架的基本功能持续完善。。。