所需依赖添加在项目中的pubspec.yaml中:
dio: ^4.0.6 #网络请求
connectivity_plus: ^2.3.6 #网络监测
pretty_dio_logger: ^1.1.1 #日志打印
class HttpRequest {
// 单例模式使用Http类,
static final HttpRequest _instance = HttpRequest._internal();
factory HttpRequest() => _instance;
static late final Dio dio;
/// 内部构造方法
HttpRequest._internal() {
/// 初始化dio
BaseOptions options = BaseOptions(
connectTimeout: HttpOptions.connectTimeout,
receiveTimeout: HttpOptions.receiveTimeout,
sendTimeout: HttpOptions.sendTimeout,
baseUrl: HttpOptions.baseUrl);
dio = Dio(options);
/// 添加各种拦截器
dio.interceptors.add(ErrorInterceptor());
dio.interceptors.add(PrettyDioLogger(
requestHeader: true,
requestBody: true,
responseHeader: true,
responseBody: true));
}
/// 封装request方法
Future request({
required String path,
required HttpMethod method,
dynamic data,
Map? queryParameters,
bool showLoading = true,
bool showErrorMessage = true,
}) async {
const Map methodValues = {
HttpMethod.get: 'get',
HttpMethod.post: 'post',
HttpMethod.put: 'put',
HttpMethod.delete: 'delete',
HttpMethod.patch: 'patch',
HttpMethod.head: 'head'
};
//动态添加header头
Map headers = Map();
headers["version"] = "1.0.0";
Options options = Options(
method: methodValues[method],
headers: headers,
);
try {
if (showLoading) {
EasyLoading.show(status: 'loading...');
}
Response response = await HttpRequest.dio.request(
path,
data: data,
queryParameters: queryParameters,
options: options,
);
return response.data;
} on DioError catch (error) {
HttpException httpException = error.error;
if (showErrorMessage) {
EasyLoading.showToast(httpException.msg);
}
} finally {
if (showLoading) {
EasyLoading.dismiss();
}
}
}
}
enum HttpMethod {
get,
post,
delete,
put,
patch,
head,
}
class ErrorInterceptor extends Interceptor {
@override
void onError(DioError err, ErrorInterceptorHandler handler) async {
/// 根据DioError创建HttpException
HttpException httpException = HttpException.create(err);
/// dio默认的错误实例,如果是没有网络,只能得到一个未知错误,无法精准的得知是否是无网络的情况
/// 这里对于断网的情况,给一个特殊的code和msg
if (err.type == DioErrorType.other) {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.none) {
httpException = HttpException(code: -100, msg: 'None Network.');
}
}
/// 将自定义的HttpException
err.error = httpException;
/// 调用父类,回到dio框架
super.onError(err, handler);
}
}
class HttpException implements Exception {
final int code;
final String msg;
HttpException({
this.code = -1,
this.msg = 'unknow error',
});
@override
String toString() {
return 'Http Error [$code]: $msg';
}
factory HttpException.create(DioError error) {
/// dio异常
switch (error.type) {
case DioErrorType.cancel:
{
return HttpException(code: -1, msg: 'request cancel');
}
case DioErrorType.connectTimeout:
{
return HttpException(code: -1, msg: 'connect timeout');
}
case DioErrorType.sendTimeout:
{
return HttpException(code: -1, msg: 'send timeout');
}
case DioErrorType.receiveTimeout:
{
return HttpException(code: -1, msg: 'receive timeout');
}
case DioErrorType.response:
{
try {
int statusCode = error.response?.statusCode ?? 0;
// String errMsg = error.response.statusMessage;
// return ErrorEntity(code: errCode, message: errMsg);
switch (statusCode) {
case 400:
{
return HttpException(code: statusCode, msg: 'Request syntax error');
}
case 401:
{
return HttpException(code: statusCode, msg: 'Without permission');
}
case 403:
{
return HttpException(code: statusCode, msg: 'Server rejects execution');
}
case 404:
{
return HttpException(code: statusCode, msg: 'Unable to connect to server');
}
case 405:
{
return HttpException(code: statusCode, msg: 'The request method is disabled');
}
case 500:
{
return HttpException(code: statusCode, msg: 'Server internal error');
}
case 502:
{
return HttpException(code: statusCode, msg: 'Invalid request');
}
case 503:
{
return HttpException(code: statusCode, msg: 'The server is down.');
}
case 505:
{
return HttpException(code: statusCode, msg: 'HTTP requests are not supported');
}
default:
{
return HttpException(
code: statusCode, msg: error.response?.statusMessage ?? 'unknow error');
}
}
} on Exception catch (_) {
return HttpException(code: -1, msg: 'unknow error');
}
}
default:
{
return HttpException(code: -1, msg: error.message);
}
}
}
}
class HttpOptions {
/// 超时时间;单位是ms
static const int connectTimeout = 15000;
static const int receiveTimeout = 15000;
static const int sendTimeout = 15000;
/// 地址域名前缀
static const String baseUrl = '************';
}
/// 调用底层的request,重新提供get,post等方便方法
class HttpUtils {
static HttpRequest httpRequest = HttpRequest();
/// get
static Future get({
required String path,
Map? queryParameters,
bool showLoading = true,
bool showErrorMessage = true,
}) {
return httpRequest.request(
path: path,
method: HttpMethod.get,
queryParameters: queryParameters,
showLoading: showLoading,
showErrorMessage: showErrorMessage,
);
}
/// post
static Future post({
required String path,
required HttpMethod method,
dynamic data,
bool showLoading = true,
bool showErrorMessage = true,
}) {
return httpRequest.request(
path: path,
method: HttpMethod.post,
data: data,
showLoading: showLoading,
showErrorMessage: showErrorMessage,
);
}
}