You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用built_value反序列化JSON时遇类型转换错误求助

解决built_value反序列化时的类型转换错误

我在Flutter项目里用built_value定义了对应JSON结构的PODO类,执行flutter packages pub run build_runner build生成代码后,HTTP请求反序列化时碰到了这个错误:

Deserializing '{status: 1, msg: Success, data: {lastIndex: 50, studentData: [{student_id: 62...' to 'StudentModel' failed due to: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable' in type cast

用普通PODO类的时候完全没问题,想问下怎么解决?


我的代码片段

PODO类代码

library student_model;
import 'dart:convert';
import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
part 'student_model.g.dart';
abstract class StudentModel implements Built<StudentModel, StudentModelBuilder> {
 StudentModel._();
 factory StudentModel([updates(StudentModelBuilder b)]) = _$StudentModel;
 @BuiltValueField(wireName: 'status')
 int get status;
 @BuiltValueField(wireName: 'msg')
 String get msg;
 @BuiltValueField(wireName: 'data')
 StudentModelData get data;
 static Serializer<StudentModel> get serializer => _$studentModelSerializer;
}
abstract class StudentModelData implements Built<StudentModelData, StudentModelDataBuilder> {
 StudentModelData._();
 factory StudentModelData([updates(StudentModelDataBuilder b)]) = _$StudentModelData;
 @BuiltValueField(wireName: 'lastIndex')
 int get lastIndex;
 @BuiltValueField(wireName: 'studentData')
 BuiltList<StudentData> get studentData;
 static Serializer<StudentModelData> get serializer => _$studentModelDataSerializer;
}
abstract class StudentData implements Built<StudentData,StudentDataBuilder> {
 StudentData._();
 factory StudentData([updates(StudentDataBuilder b)]) = _$StudentData;
 @BuiltValueField(wireName: 'student_id')
 String get studentId;
 @BuiltValueField(wireName: 'stud_name')
 String get studentName;
 @BuiltValueField(wireName: 'stud_profilepic')
 String get studentProfilePicture;
 @BuiltValueField(wireName: 'student_email')
 String get studentEmail;
 @BuiltValueField(wireName: 'course_name')
 String get courseName;
 @BuiltValueField(wireName: 'class_code')
 String get classCode;
 @BuiltValueField(wireName: 'minAvg')
 int get minAverage;
 @BuiltValueField(wireName: 'avg')
 int get average;
 static Serializer<StudentData> get serializer => _$studentDataSerializer;
}

序列化类代码

library serializers;
import 'package:built_value/serializer.dart';
import 'package:built_collection/built_collection.dart';
import 'package:built_value/standard_json_plugin.dart';
import 'package:infinite_list/models/student_model.dart';
part 'serializers.g.dart';
@SerializersFor(const [StudentModel,])
Serializers serializers = _$serializers;
Serializers standardSerializers = (serializers.toBuilder()..addPlugin(StandardJsonPlugin())).build();

HTTP请求代码

Future<StudentModel> fetchStudents(String disciplineId, String schoolId, String year_id, String lastIndex) async {
 final response = await http.post(GET_STUDENTS, body: {
 "schoolId": schoolId,
 "year_id": year_id,
 });
 StudentModel studentModel = serializers.deserializeWith(StudentModel.serializer, json.decode(response.body));
 return studentModel;
}

问题原因&解决方案

核心问题

你只在@SerializersFor注解里添加了StudentModel,但嵌套的StudentModelData和StudentData的序列化器没被注册到序列化器集合中。built_value在解析data字段时,找不到对应的类型处理逻辑,错误地把它当成了可迭代类型(Iterable)来转换,于是抛出了类型不匹配的异常。

修复步骤

1. 更新序列化类,注册所有模型

把所有相关的模型类都添加到@SerializersFor的列表里:

library serializers;
import 'package:built_value/serializer.dart';
import 'package:built_collection/built_collection.dart';
import 'package:built_value/standard_json_plugin.dart';
import 'package:infinite_list/models/student_model.dart';
part 'serializers.g.dart';

// 加入所有需要序列化的模型类
@SerializersFor(const [StudentModel, StudentModelData, StudentData])
Serializers serializers = _$serializers;
Serializers standardSerializers = (serializers.toBuilder()..addPlugin(StandardJsonPlugin())).build();

2. 使用带插件的序列化器反序列化

你已经添加了StandardJsonPlugin来处理普通JSON格式,但之前的代码用的是原始的serializers,应该换成standardSerializers:

Future<StudentModel> fetchStudents(String disciplineId, String schoolId, String year_id, String lastIndex) async {
 final response = await http.post(GET_STUDENTS, body: {
 "schoolId": schoolId,
 "year_id": year_id,
 });
 // 改用standardSerializers
 StudentModel studentModel = standardSerializers.deserializeWith(StudentModel.serializer, json.decode(response.body));
 return studentModel;
}

3. 重新生成代码

修改完成后,执行命令重新生成序列化相关代码:

flutter packages pub run build_runner build --delete-conflicting-outputs

这样处理后,序列化器就能正确识别所有嵌套的模型类型,完美完成JSON到built_value对象的转换了。

内容的提问来源于stack exchange,提问作者BraveEvidence

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:48:32