您的位置:首页 > 文旅 > 美景 > 网站首页推广_在线设计平台行业概况_网络推广运营主要做什么_站长平台

网站首页推广_在线设计平台行业概况_网络推广运营主要做什么_站长平台

2024/12/23 4:48:45 来源:https://blog.csdn.net/sziitjin/article/details/143356281  浏览:    关键词:网站首页推广_在线设计平台行业概况_网络推广运营主要做什么_站长平台
网站首页推广_在线设计平台行业概况_网络推广运营主要做什么_站长平台

在移动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();Map<String, String> params = {};/// 添加参数BaseRequest add(String k, Object v) {params[k] = v.toString();return this;}Map<String, 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;}Future<dynamic> send<T>(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 HiNetResponse<T> {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 {Future<HiNetResponse<T>> send<T>(BaseRequest request);
}/// 统一网络层返回格式
class HiNetResponse<T> {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 {@overrideFuture<HiNetResponse<T>> send<T>(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);}}Future<dynamic> send<T>(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 {@overrideFuture<HiNetResponse<T>> send<T>(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);}/// 构建HiNetResponseHiNetResponse<T> buildResponse<T>(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 {Future<dynamic> send<T>(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(Map<String, dynamic> json) => _$TestModelFromJson(json);//固定格式,Map<String, 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解析类时,手动创建的基类Model(TestModel),必须满足以下要求:

1. 在Model类编写 part '同Model类文件名.g.dart'; 如 TestModel类文件名est_model.dart ,则编写 part 'test_model.g.dart';

2.增加注解: @JsonSerializable()

3.编写固定格式的代码,名字换成基类名字,这里是TestModel:

  //固定格式,不同的类使用不同的mixin即可factory TestModel.fromJson(Map<String, dynamic> json) => _$TestModelFromJson(json);//固定格式,Map<String, 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: 

至此,完成了网络请求框架的基本功能,持续完善。。。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com