【2022-06-18更新】
下面的篇幅是比较初期的思路总结,最近抽时间把逻辑梳理好了整理出来一段实例代码:
如果觉得对您有帮助的话,请不吝给个星星,万分感激
目前做的app后台使用的是json格式来处理网络请求并返回数据,返回的json格式比较统一:
//成功
{
"success":true,
"data":{
"result":"哈哈"
}
}
//失败
{
"success":false,
"error_code":401,
"error_message":"用户登录超时"
}
因此针对返回数据做了一个简单地封装:
一、封装model
这里对于data我没有进行处理,由于data的类型不能确定,后面会放在实现类里:
dart好像不能重写没有类方法?为了方便我把请求细节如header、url等加入了model中,后面会创建一个某个model的单例来读取请求细节。
model.dart
abstract class Model {
bool? success;
int? errorCode;
String? errorMessage;
Model? createModel(dynamic json);
String url();
String domain();
Method method();
Map<String, dynamic> header();
}
constant.dart
const Domain = "https://baidu.com/api";
header.dart
//header的内容自己把握
class Header {
static late LoginService loginService = LoginService.service;
static Map<String, dynamic> get unLoginHeader => {
"Phone-Type": "i",
"version": "1.2.0",
"User-Agent":
"Mozilla/5.0 (iPhone; CPU iPhone OS 12_4_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13G36",
};
static Map<String, dynamic> get loginHeader => {
"Phone-Type": "i",
"version": "1.2.0",
"User-Agent":
"Mozilla/5.0 (iPhone; CPU iPhone OS 12_4_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13G36",
"Authorization": "jwt ${loginService.token.value.data?.accessToken}",
};
}
method.dart
enum Method {
GET,
POST,
PUT,
DELETE,
HEAD,
}
下面是对于model的一个实现:
model的json为:
{
"success": true,
"data": {
"info": 1,
"avatar": "",
"mobile": "1777777777",
"area": "",
"birthday": "",
"gender": 0,
"nickname": "蒙古上单",
"vip": 0,
}
}
user_info_model.dart
//此文件是使用AS的JSONToDart插件转换后修改的,转换的时候不需要勾选generate private fields
import 'package:FlutterWorkspace/model/model.dart';
import 'package:FlutterWorkspace/network/constants.dart';
import 'package:FlutterWorkspace/network/header.dart';
import 'package:FlutterWorkspace/network/method.dart';
class UserInfoModel implements Model {
Data? data;
bool? success;
int? errorCode;
String? errorMessage;
UserInfoModel({this.data, this.success});
UserInfoModel.fromJson(dynamic json) {
data = json['data'] != null ? Data.fromJson(json['data']) : null;
success = json['success'];
errorCode = json['error_code'];
errorMessage = json['error_message'];
}
Map<String, dynamic> toJson() {
var map = <String, dynamic>{};
if (data != null) {
map['data'] = data?.toJson();
}
map['success'] = success;
return map;
}
@override
Model? createModel(dynamic json) => UserInfoModel.fromJson(json);
@override
String domain() => Domain;
@override
Map<String, dynamic> header() => Header.loginHeader;
@override
Method method() => Method.GET;
@override
String url() =>"info";//最终的请求地址是https://baidu.com/api/info
}
class Data {
int? info;
String? avatar;
String? mobile;
String? area;
String? birthday;
int? gender;
String? nickname;
int? vip;
Data({this.info,
this.avatar,
this.mobile,
this.area,
this.birthday,
this.gender,
this.nickname,
this.vipFirst,
this.vip});
Data.fromJson(dynamic json) {
info = json['info'];
avatar = json['avatar'];
mobile = json['mobile'];
area = json['area'];
birthday = json['birthday'];
gender = json['gender'];
nickname = json['nickname'];
vip = json['vip'];
}
Map<String, dynamic> toJson() {
var map = <String, dynamic>{};
map['info'] = info;
map['avatar'] = avatar;
map['mobile'] = mobile;
map['area'] = area;
map['birthday'] = birthday;
map['gender'] = gender;
map['nickname'] = nickname;
map['vip'] = vip;
return map;
}
}
最后封装一个UserInfoMode的单例用来标记发送哪个请求:
model.dart
import 'package:FlutterWorkspace/model/user_info_model/user_info_model.dart';
extension ModelSingleTon on Model {
static Model userInfoModel = UserInfoModel();
}
封装dio
networking.dart
import 'package:FlutterWorkspace/model/model.dart';
import 'package:dio/dio.dart';
//dio方法封装
class NetworkUtil {
Future<Response?> doRequest(Method method, String baseUrl, String url,
Map<String, dynamic> header, data, Map<String, dynamic>? queryParameters,
{String contentType = Headers.jsonContentType}) async {
var dio = Dio(BaseOptions(
baseUrl: baseUrl,
connectTimeout: 5000,
receiveTimeout: 60000,
headers: header,
contentType: contentType,
responseType: ResponseType.json));
Response? response;
try {
switch (method) {
case Method.GET:
response = await dio.get(url, queryParameters: queryParameters);
break;
case Method.POST:
response =
await dio.post(url, data: data, queryParameters: queryParameters);
break;
case Method.PUT:
break;
default:
break;
}
} on DioError catch (e) {
switch (e.type) {
case DioErrorType.connectTimeout:
print("------------连接服务器超时--------------");
break;
case DioErrorType.sendTimeout:
case DioErrorType.receiveTimeout:
print("------------服务器响应超时--------------");
break;
default:
break;
}
return null;
} on Error catch (e) {
print("-----------请求失败---------$e");
}
return response;
}
//请求model
Future<Response?> doModelRequest(
Model model, data, Map<String, dynamic>? params) async {
return await doRequest(model.method(), model.domain(), model.url(),
model.header(), data, params);
}
}
使用
以请求UserInfoModel为例
NetworkUtil _networkUtil = NetworkUtil();
UserInfoModel? model = await _networkUtil.requestModel(
ModelSingleTon.userInfoModel, null, null) as UserInfoModel;
如果是带请求参数如https://baidu.com/api/info?name=haha
UserInfoModel? model = await _networkUtil.requestModel(
ModelSingleTon.userInfoModel, null, {"name","haha"}) as UserInfoModel;
发送body:
UserInfoModel? model = await _networkUtil.requestModel(
ModelSingleTon.userInfoModel, {"aaa":"1"}, null) as UserInfoModel;