Flutter Dio网络请求:定位空值字段类型不匹配报错方案咨询
解决Dio解析嵌套JSON时空值字段定位问题
针对你遇到的Dio解析复杂/嵌套JSON时无法定位具体空值字段的问题,以下是几种实用方案:
1. 自定义JSON解析错误捕获与定位
手动封装模型转换逻辑,在解析每个字段时捕获空值异常,并记录字段路径:
class User { final String id; final Profile profile; User({required this.id, required this.profile}); factory User.fromJson(Map<String, dynamic> json) { try { return User( id: _parseField(json, 'id'), profile: Profile.fromJson(_parseField(json, 'profile')), ); } catch (e) { throw Exception('解析User模型失败: ${e.toString()}'); } } } class Profile { final String name; final int age; Profile({required this.name, required this.age}); factory Profile.fromJson(Map<String, dynamic> json) { try { return Profile( name: _parseField(json, 'name'), age: _parseField(json, 'age'), ); } catch (e) { throw Exception('解析Profile模型失败: ${e.toString()}'); } } } T _parseField<T>(Map<String, dynamic> json, String key) { final value = json[key]; if (value == null) { throw Exception('字段 [$key] 为空,无法转换为类型 ${T.runtimeType}'); } if (value is! T) { throw Exception('字段 [$key] 类型不匹配,期望 ${T.runtimeType},实际 ${value.runtimeType}'); } return value; }
解析时会直接抛出包含字段路径的错误,比如解析Profile模型失败: 字段 [name] 为空,无法转换为类型 String,快速定位问题字段。
2. 基于json_serializable增强错误提示
如果你使用json_serializable生成模型,可以通过自定义JsonConverter添加字段路径追踪:
先创建带路径的转换器:
class TrackedConverter<T> extends JsonConverter<T, dynamic> { final String fieldPath; const TrackedConverter(this.fieldPath); @override T fromJson(dynamic json) { if (json == null) { throw Exception('字段 [$fieldPath] 为空,无法转换为 ${T.runtimeType}'); } if (json is! T) { throw Exception('字段 [$fieldPath] 类型不匹配: 期望 ${T.runtimeType}, 实际 ${json.runtimeType}'); } return json; } @override dynamic toJson(T object) => object; }
再在模型中使用:
import 'package:json_annotation/json_annotation.dart'; part 'user.g.dart'; @JsonSerializable() class User { @TrackedConverter('user.id') final String id; @TrackedConverter('user.profile') final Profile profile; User({required this.id, required this.profile}); factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); } @JsonSerializable() class Profile { @TrackedConverter('user.profile.name') final String name; @TrackedConverter('user.profile.age') final int age; Profile({required this.name, required this.age}); factory Profile.fromJson(Map<String, dynamic> json) => _$ProfileFromJson(json); }
生成代码后,解析时若出现空值或类型不匹配,会直接抛出带完整路径的错误信息。
3. 封装Dio响应拦截器统一处理
通过Dio拦截器,在响应解析阶段统一捕获异常,并结合模型结构生成详细错误信息:
class ParseErrorInterceptor extends InterceptorsWrapper { @override void onResponse(Response response, ResponseInterceptorHandler handler) { try { // 这里假设解析成User模型,实际可根据请求动态调整 final data = User.fromJson(response.data); handler.next(response.copyWith(data: data)); } catch (e) { final errorMsg = 'API响应解析失败: ${e.toString()}'; handler.reject(DioError( requestOptions: response.requestOptions, response: response, error: errorMsg, )); } } } // 添加到Dio实例 final dio = Dio(); dio.interceptors.add(ParseErrorInterceptor());
结合前面的自定义解析逻辑,拦截器会把详细的字段错误信息带到DioError中,方便在请求回调中直接获取。
这些方案都能让你像使用Retrofit一样,明确知道哪个字段出现了空值或类型不匹配问题,无需手动排查整个嵌套模型。
内容的提问来源于stack exchange,提问作者Md Eusuf Uddin
相关产品推荐
相关产品推荐

