通过例子比较了
HttpClient,http和dio,github star和功能丰富性,选择在项目中使用dio请求网络;
json_serializable+json_annotation可以作为json序列化方式,不喜欢这种方式;
我选择的在https://javiercbk.github.io/json_to_dart/把基类json生成dart class实体类,
其他类使用插件FlutterJsonBeanFactory生成dart class实体类,插件安装后记得重启IDE
pubspec.yaml 添加 dio依赖
dio: ^3.0.9
网络工具类
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
class HttpManager {
static HttpManager _instance;
static HttpManager getInstance() {
if (_instance == null) {
_instance = new HttpManager();
}
return _instance;
}
HttpManager() {
dio = createInstance();
}
/// global dio object
static Dio dio;
/// default options
static const String _BASE_URL = "https://www.wanandroid.com/";
static const int _CONNECT_TIMEOUT = 15000;
static const int _RECEIVE_TIMEOUT = 15000;
/// http request methods
static const String GET = 'get';
static const String POST = 'post';
static const String PUT = 'put';
static const String PATCH = 'patch';
static const String DELETE = 'delete';
get<T>(
String url, FormData param, Function onSuccess, Function onError) async {
requestHttp<T>(
url,
param: param,
method: GET,
onSuccess: onSuccess,
onError: onError,
);
}
post<T>(
String url, FormData param, Function onSuccess, Function onError) async {
requestHttp<T>(
url,
param: param,
method: POST,
onSuccess: onSuccess,
onError: onError,
);
}
/// T is Map<String,dynamic> or List<dynamic>
static requestHttp<T>(
String url, {
param,
method,
Function(T map) onSuccess,
Function(String error) onError,
}) async {
dio = createInstance();
try {
Response response = await dio.request(
url,
data: param,
options: new Options(method: method),
);
if (response.statusCode == HttpStatus.ok) {
onSuccess(json.decode(response.data));
} else {
onError("【statusCode】${response.statusCode}");
}
} on DioError catch (e) {
/// 打印请求失败相关信息
print("【请求出错】${e.toString()}");
onError(e.toString());
}
}
/// 创建 dio 实例对象
static Dio createInstance() {
if (dio == null) {
/// 全局属性:请求前缀、连接超时时间、响应超时时间
var options = new BaseOptions(
baseUrl: _BASE_URL,
connectTimeout: _CONNECT_TIMEOUT,
receiveTimeout: _RECEIVE_TIMEOUT,
responseType: ResponseType.plain,
// contentType: Headers.jsonContentType,
);
dio = new Dio(options);
dio.interceptors.add(new LogInterceptors());
}
return dio;
}
// /// request method
// static Future<Map> request<T>(
// String url, {
// param,
// method,
// Function onSuccess,
// Function onError,
// }) async {
param = param ?? {};
//
// /// restful 请求处理
// /// /gysw/search/hist/:user_id user_id=27
// /// 最终生成 url 为 /gysw/search/hist/27
// param.forEach((key, value) {
// if (url.indexOf(key) != -1) {
// url = url.replaceAll(':$key', value.toString());
// }
// });
//
// dio = createInstance();
// var result;
// try {
// Response response = await dio.request(
// url,
// data: param,
// options: new Options(method: method),
// );
// result = json.decode(response.data);
// if (response.statusCode == HttpStatus.ok) {
// onSuccess(result);
// } else {
// onError("【statusCode】${response.statusCode}");
// }
// } on DioError catch (e) {
// /// 打印请求失败相关信息
// print("【请求出错】${e.toString()}");
// onError(e.toString());
// }
// return result;
// }
/// 清空 dio 对象
static clear() {
dio = null;
}
}
///日志拦截器
class LogInterceptors extends InterceptorsWrapper {
@override
Future onRequest(RequestOptions options) {
print("【请求baseUrl】${options.baseUrl}");
print("【请求path】${options.path}");
print("【请求headers】${options.headers.toString()}");
//todo 参数拦截
print("【请求参数】${options.data.toString()}");
return super.onRequest(options);
}
@override
Future onResponse(Response response) {
print("【返回statusCode】${response.statusCode}");
print("【返回headers】${response.headers.toString()}");
print("【返回extra】${response.extra.toString()}");
print("【返回data】${response.data.toString()}");
return super.onResponse(response);
}
@override
Future onError(DioError err) {
print(err.toString());
print(err.response?.toString());
return super.onError(err);
}
}
相应基类定义
///convert和FlutterJsonBeanFactory结合解析
class BaseEntity<T> {
T data;
int errorCode;
String errorMsg;
BaseEntity({this.data, this.errorCode, this.errorMsg});
BaseEntity.fromJson(Map<String, dynamic> json) {
if (json['data'] != null&&json['data']!='null') {
data = JsonConvert.fromJsonAsT<T>(json['data']);
}
errorCode = json['errorCode'];
errorMsg = json['errorMsg'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.data != null) {
data['data'] = this.data;
}
data['errorCode'] = this.errorCode;
data['errorMsg'] = this.errorMsg;
return data;
}
}
JsonConvert.fromJsonAsT<T>(json['data']); 是FlutterJsonBeanFactory生成的,判断了Object或List类型分别解析
使用
HttpManager.getInstance().get("banner/json", null, (data) {
BaseEntity<List<BannerEntity>> baseEntity = BaseEntity.fromJson(data);
baseEntity.data.forEach((element) {
print(element.imagePath);
});
}, (error) {
ToastUtil.showToastCenter(error);
});
post请求
var map = Map<String, String>();
map["username"] = "江渚清沨";
map["password"] = "xxxxx";
FormData formData = FormData.fromMap(map);
HttpManager.getInstance().post("user/login", formData, (data) {
BaseEntity<UserEntity> baseModel = BaseEntity.fromJson(data);
print("解析${baseModel.errorMsg}");
}, (error) {
ToastUtil.showToastCenter(error);
});