LogInterceptor
/// [LogInterceptor] is used to print logs during network requests.
/// It's better to add [LogInterceptor] to the tail of the interceptor queue,
/// otherwise the changes made in the interceptor behind A will not be printed out.
/// This is because the execution of interceptors is in the order of addition.
class LogInterceptor extends Interceptor {
LogInterceptor({
this.request = true,
this.requestHeader = true,
this.requestBody = false,
this.responseHeader = true,
this.responseBody = false,
this.error = true,
this.logPrint = print,
});
/// Print request [Options]
bool request;
/// Print request header [Options.headers]
bool requestHeader;
/// Print request data [Options.data]
bool requestBody;
/// Print [Response.data]
bool responseBody;
/// Print [Response.headers]
bool responseHeader;
/// Print error message
bool error;
/// Log printer; defaults print log to console.
/// In flutter, you'd better use debugPrint.
/// you can also write log in a file, for example:
///```dart
/// final file=File("./log.txt");
/// final sink=file.openWrite();
/// dio.interceptors.add(LogInterceptor(logPrint: sink.writeln));
/// ...
/// await sink.close();
///```
void Function(Object object) logPrint;
@override
void onRequest(
RequestOptions options,
RequestInterceptorHandler handler,
) async {
logPrint('*** Request ***');
_printKV('uri', options.uri);
//options.headers;
if (request) {
_printKV('method', options.method);
_printKV('responseType', options.responseType.toString());
_printKV('followRedirects', options.followRedirects);
_printKV('persistentConnection', options.persistentConnection);
_printKV('connectTimeout', options.connectTimeout);
_printKV('sendTimeout', options.sendTimeout);
_printKV('receiveTimeout', options.receiveTimeout);
_printKV(
'receiveDataWhenStatusError',
options.receiveDataWhenStatusError,
);
_printKV('extra', options.extra);
}
if (requestHeader) {
logPrint('headers:');
options.headers.forEach((key, v) => _printKV(' $key', v));
}
if (requestBody) {
logPrint('data:');
_printAll(options.data);
}
logPrint('');
handler.next(options);
}
@override
void onResponse(Response response, ResponseInterceptorHandler handler) async {
logPrint('*** Response ***');
_printResponse(response);
handler.next(response);
}
@override
void onError(DioError err, ErrorInterceptorHandler handler) async {
if (error) {
logPrint('*** DioError ***:');
logPrint('uri: ${err.requestOptions.uri}');
logPrint('$err');
if (err.response != null) {
_printResponse(err.response!);
}
logPrint('');
}
handler.next(err);
}
void _printResponse(Response response) {
_printKV('uri', response.requestOptions.uri);
if (responseHeader) {
_printKV('statusCode', response.statusCode);
if (response.isRedirect == true) {
_printKV('redirect', response.realUri);
}
logPrint('headers:');
response.headers.forEach((key, v) => _printKV(' $key', v.join('\r\n\t')));
}
if (responseBody) {
logPrint('Response Text:');
_printAll(response.toString());
}
logPrint('');
}
void _printKV(String key, Object? v) {
logPrint('$key: $v');
}
void _printAll(msg) {
msg.toString().split('\n').forEach(logPrint);
}
}
LogInterceptor 是用于在网络请求期间打印日志的拦截器。
它可以打印请求和响应的详细信息,包括请求URL、请求头、请求数据、响应状态码、响应头以及响应数据等。你可以根据需要设置哪些信息需要打印。
以下是 LogInterceptor 提供的参数和功能:
request: 是否打印请求的基本信息。requestHeader: 是否打印请求的头部信息。requestBody: 是否打印请求的数据信息。responseHeader: 是否打印响应的头部信息。responseBody: 是否打印响应的数据信息。error: 是否打印错误信息。logPrint: 用于打印日志的回调函数,默认是打印到控制台。
在具体的请求、响应和错误处理方法中,LogInterceptor 根据设置的参数,打印相关信息。
例如,在请求方法中,会打印请求的基本信息、头部信息和数据信息。在响应方法中,会打印响应的基本信息、头部信息和数据信息。在错误方法中,会打印错误信息。
使用 LogInterceptor 可以帮助你在开发过程中更方便地跟踪和调试网络请求,了解请求和响应的具体细节。但需要注意,在生产环境中,建议关闭或移除日志拦截器,以避免不必要的信息暴露。
CacheInterceptor
class CacheInterceptor extends Interceptor {
CacheInterceptor();
final _cache = <Uri, Response>{};
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
final response = _cache[options.uri];
if (options.extra['refresh'] == true) {
print('${options.uri}: force refresh, ignore cache! \n');
return handler.next(options);
} else if (response != null) {
print('cache hit: ${options.uri} \n');
return handler.resolve(response);
}
super.onRequest(options, handler);
}
@override
void onResponse(Response response, ResponseInterceptorHandler handler) {
_cache[response.requestOptions.uri] = response;
super.onResponse(response, handler);
}
@override
void onError(DioError err, ErrorInterceptorHandler handler) {
print('onError: $err');
super.onError(err, handler);
}
}
CacheInterceptor 是一个自定义的拦截器,用于实现简单的请求缓存功能。它可以在请求发送前检查缓存是否存在,并在响应返回后将响应数据缓存起来,以便在后续相同请求时直接返回缓存数据,避免重复请求。
该拦截器具有以下功能:
_cache: 一个存储缓存数据的字典,使用请求的 URI 作为键,响应数据作为值。
在请求方法中,它会检查缓存中是否存在对应的响应数据。如果存在,则直接返回缓存的响应数据,而不再进行实际的网络请求。如果请求中设置了 refresh 参数为 true,则会强制刷新数据,忽略缓存,并继续进行实际的网络请求。
在响应方法中,它会将收到的响应数据缓存起来,以便后续的相同请求可以直接返回缓存数据。
在错误方法中,它会简单地打印错误信息。
注意:这只是一个简单的示例实现,实际的缓存机制可能更复杂,例如可以设置缓存的有效期、清除过期的缓存等。缓存策略通常需要根据具体的应用场景进行定制。