建议先将Flutter官方文档过一遍,本系列教程 Flutter SDK >= 3.10.0
考虑篇幅长度,这里将分成几片文章
一、创建错误响应实体类
lib/utils/http/error.dart
abstract class BaseError {
final int code;
final String message;
BaseError({required this.code, required this.message});
}
class NeedLogin implements BaseError {
int get code => 401;
String get message => "请先登录";
}
class NeedAuth implements BaseError {
int get code => 403;
String get message => "非法访问,请使用正确的token";
}
class UserNotExist implements BaseError {
int get code => 408;
String get message => "用户不存在";
}
class UserNameEmpty implements BaseError {
int get code => 405;
String get message => "用户名不能为空";
}
class PwdNotMatch implements BaseError {
int get code => 409;
String get message => "用户密码不正确";
}
class PwdEmpty implements BaseError {
int get code => 406;
String get message => "用户密码不能为空";
}
class OtherError implements BaseError {
final int statusCode;
final String statusMessage;
OtherError({required this.statusCode, required this.statusMessage});
int get code => statusCode;
String get message => statusMessage;
}
二、创建Http拦截器
lib/utils/http/interceptor.dart
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:lhdht_flutter_app/mixins/logger.dart';
import 'package:lhdht_flutter_app/model/response/base_response_entity.dart';
class HttpInterceptor extends Interceptor with LoggerHelper {
late DateTime startTime;
late DateTime endTime;
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
startTime = DateTime.now();
if (kDebugMode) {
print("-------- Http Interceptor start --------");
}
return handler.next(options);
}
void onResponse(Response response, ResponseInterceptorHandler handler) {
endTime = DateTime.now();
int duration = endTime.difference(startTime).inMilliseconds;
BaseResponseEntity res = BaseResponseEntity.fromJson(response.data); // 解析数据
response.data = res.data;
if (kDebugMode) {
print("-------- Http Interceptor end: $duration 毫秒 --------");
}
return handler.next(response);
}
}
三、封装Dio
lib/utils/http/entrance.dart
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:flutter/foundation.dart';
import 'package:lhdht_flutter_app/config/global.dart';
import 'package:lhdht_flutter_app/utils/http/interceptor.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
import 'error.dart';
class Http {
static final Http _instance = Http._();
static Http get instance => Http();
factory Http() => _instance;
static late Dio _dio;
Dio get dio => _dio;
Http._() {
// 构造 Dio options
final BaseOptions options = BaseOptions(
receiveTimeout: const Duration(seconds: 10),
connectTimeout: const Duration(seconds: 10),
sendTimeout: const Duration(seconds: 8),
responseType: ResponseType.plain,
validateStatus: (_) => true,
baseUrl: GlobalConfig.baseURL,
);
_dio = Dio(options);
// 忽略 https 证书校验
if (kDebugMode) {
(_dio.httpClientAdapter as IOHttpClientAdapter).onHttpClientCreate = (HttpClient client) {
client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;
return client;
};
// 日志
_dio.interceptors.add(PrettyDioLogger(
requestHeader: true,
requestBody: true,
responseBody: true,
responseHeader: true,
error: true,
compact: true,
maxWidth: 90
));
}
_dio.interceptors.add(HttpInterceptor());
}
BaseError getError(Object obj) { // 这里封装了一个 BaseError 类,会根据后端返回的code返回不同的错误类
switch (obj.runtimeType) {
case DioError:
if ((obj as DioError).type == DioErrorType.badResponse) {
final response = (obj).response;
if (response?.statusCode == 401) {
return NeedLogin();
} else if (response?.statusCode == 403) {
return NeedAuth();
} else if (response?.statusCode == 408) {
return UserNotExist();
} else if (response?.statusCode == 409) {
return PwdNotMatch();
} else if (response?.statusCode == 405) {
return UserNameEmpty();
} else if (response?.statusCode == 406) {
return PwdEmpty();
} else {
return OtherError(
statusCode: response?.statusCode as int,
statusMessage: response?.statusMessage as String,
);
}
}
}
return OtherError(statusCode: -1, statusMessage: '未知错误');
}
}