HTTP
网络请求每个项目会用到,封装一个好用HTTP
网络请求工具很有必要,下面是基于 dio 进行的二次封装。
封装的目标:
- 请求前缀
header
- 打印请求/响应/报错信息
- 返回数据自动转成
json
和对象 - 请求结果处理
使用到的工具:
- dio :Flutter中国的网络请求库
-
FlutterJsonBeanFactory
:json
自动生成dart
实体类插件
导入库和安装插件
依赖:
dependencies:
dio: ^2.1.16
安装:
packages get
导入:
import 'package:dio/dio.dart';
- 安装
FlutterJsonBeanFactory
插件
打开Android Studio
的 Plugins
搜索 FlutterJsonBeanFactory
:
安装并重启AS,新建文件看到JsonToDartBeanAction
说明安装成功:
封装
HTTP工具类:util/http.dart
:
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_framework/constants/constants.dart';
/// HTTP请求工具类
class Http {
/// 公开同步单例访问点
factory Http() => _sharedInstance();
/// 公开静态单例访问点
static get instance => _sharedInstance();
/// 私有静态实例成员,未初始化
static Http _instance;
/// 同步/静态单例访问点
static Http _sharedInstance() {
if (_instance == null) {
_instance = Http._();
}
return _instance;
}
/// Dio实例
Dio dio;
/// 私有构造函数
Http._() {
dio = new Dio(BaseOptions(
method: "POST",
connectTimeout: 5000,
receiveTimeout: 15000,
contentType: ContentType.json,
responseType: ResponseType.json,
));
// dio.options.headers["Authorization"] = "这里可以设置登录后的token到headers";
// 添加拦截器
dio.interceptors.add(InterceptorsWrapper(
// 请求被发送之前
// 如果你想完成请求并返回一些自定义数据,可以返回一个`Response`对象
// 或返回`dio.resolve(data)`,这样请求将会被终止.
// 上层then会被调用,then中返回的数据将是你的自定义数据data.
//
// 如果你想终止请求并触发一个错误,你可以返回一个`DioError`对象,
// 或返回`dio.reject(errMsg)`,这样请求将被中止并触发异常,上层catchError会被调用.
onRequest: (RequestOptions options) {
print("\n================== 请求数据 ==========================");
print("url = ${options.uri.toString()}");
print("headers = ${options.headers}");
print("params = ${options.data}");
print("\n=====================================================");
return options; //continue
},
// 返回响应数据之前
onResponse: (Response response) {
print("\n================== 响应数据 ==========================");
print("code = ${response.statusCode}");
print("data = ${response.data}");
print("\n=====================================================");
return response; // continue
},
// 请求失败之前
onError: (DioError e) {
print("\n================== 错误响应数据 ======================");
print("type = ${e.type}");
print("message = ${e.message}");
print("\n=====================================================");
return e; // continue
},
));
}
/// POST请求
Future<Map<String, dynamic>> post(
{@required String url,
@required Map params,
@required onError(int code, String message)}) =>
_request(url: url, data: params, onError: onError);
/// GET请求
Future<Map<String, dynamic>> get(
{@required String url,
Map params,
@required onError(int code, String message)}) =>
_request(
url: url, queryParameters: params, onError: onError);
/// 通用请求
Future<Map<String, dynamic>> _request(
{@required String url,
Map data = const {},
Map queryParameters,
Options options,
@required onError(int code, String message)}) async {
Response<Map<String, dynamic>> response;
try {
response = await dio.request(url,
data: data, queryParameters: queryParameters, options: options);
return response.data;
} catch (e) {
//网络异常
onError(Constants.codeNetError, e.toString());
return null;
}
}
}
封装网络请求: util/request.dart
:
import 'package:flutter/foundation.dart';
import 'package:flutter_framework/api/api.dart';
import 'package:flutter_framework/constants/constants.dart';
import 'package:flutter_framework/model/message_entity.dart';
import 'http.dart';
/// 网络请求
class Request {
static Http http = Http();
///
/// 获取今日头条资讯
///
static Future<MessageEntity> getMessage(
{@required String tag,
@required int page,
@required onError(int code, String message)}) async {
var from = {
"apikey": Constants.apiKey,
"tag": tag,
"page": page,
};
var response =
await http.get(url: API.getMessage, params: from, onError: onError);
if (response != null) {
if (response["retcode"] == "0000") {
MessageEntity messageEntity =
MessageEntity.fromJson(response);
return messageEntity;
} else {
onError(response["retcode"], "请求异常,请联系管理员");
return null;
}
} else {
// response为null,表示网络出错,
// onError()方法会在http._request()内调用.
return null;
}
}
}
调用接口:
RaisedButton(
child: Text("获取数据"),
onPressed: () {
Request.getMessage(
tag: "__all__",
page: 0,
onError: (code, message) {
//请求失败
print(code.toString() + ":" + message);
}).then((message) {
//获取成功
print(message.data[0].xAbstract);
});
},
)
接口和 apikey
都是用了一个数据接口服务网站的,不免费,所以不在这里写出来了。
最后GitHub传送门:FlutterDemo