如何使用built_value正确反序列化带泛型的JSON响应数据?
如何用built_value实现泛型JSON反序列化(通用响应体)
我之前也踩过built_value泛型序列化的坑,你的问题主要出在泛型serializer的定义和serializers集合的配置上,咱们一步步来修正:
错误原因分析
你遇到的Invalid argument(s): Unknown type on deserialization错误,本质是:
- 泛型
GenericValue的serializer定义不符合built_value的泛型要求 - 没有正确将
GenericValue和UserInfo的serializer都加入到序列化器集合中 - builderFactory的注册逻辑方向正确,但缺少前置的serializer注册步骤
修正后的完整代码
import 'package:built_value/built_value.dart'; import 'package:built_value/serializer.dart'; import 'dart:convert' as json; // 修正泛型serializer的定义:Serializer<GenericValue<T>> abstract class GenericValue<T> implements Built<GenericValue<T>, GenericValueBuilder<T>> { T get data; int get status; String get msg; GenericValue._(); // 泛型类的serializer需要带泛型参数,匹配类的泛型定义 static Serializer<GenericValue<T>> serializer<T>() => _$genericValueSerializer<T>(); factory GenericValue([void Function(GenericValueBuilder<T>) updates]) = _$GenericValue<T>; } abstract class UserInfo implements Built<UserInfo, UserInfoBuilder> { static Serializer<UserInfo> get serializer => _$userInfoSerializer; String get id; String get email; UserInfo._(); factory UserInfo([void Function(UserInfoBuilder) updates]) = _$UserInfo; } // 全局预配置序列化器集合:注册所有需要的serializer和builderFactory final Serializers serializers = (standardSerializers.toBuilder() // 添加泛型实例的serializer ..add(GenericValue.serializer<UserInfo>()) // 添加实体类的serializer ..add(UserInfo.serializer) // 为具体的泛型组合注册对应的builder ..addBuilderFactory( const FullType(GenericValue, [FullType(UserInfo)]), () => GenericValueBuilder<UserInfo>(), )) .build(); GenericValue<UserInfo> parseUserInfo(String jsonStr) { final parsed = json.jsonDecode(jsonStr); final specifiedType = const FullType(GenericValue, [FullType(UserInfo)]); // 使用预配置好的serializers进行反序列化,显式类型转换 final response = serializers.deserialize(parsed, specifiedType: specifiedType) as GenericValue<UserInfo>; return response; }
关键要点说明
- 泛型Serializer的定义:
GenericValue的serializer必须是带泛型参数的Serializer<GenericValue<T>>,通过serializer<T>()方法暴露,这样built_value才能正确绑定泛型类型。 - 全局Serializers集合:所有需要用到的serializer(包括泛型实例的serializer和实体类的serializer)都必须提前加入到集合中,这是built_value序列化的核心要求。
- BuilderFactory注册:必须为具体的泛型组合(比如
GenericValue<UserInfo>)单独注册builder,因为built_value无法自动推断泛型对应的builder类型。 - 类型转换:deserialize方法返回动态类型,需要显式转为目标泛型类型(或用类型断言)。
测试用例示例
假设你的JSON数据格式如下:
{ "status": 200, "msg": "success", "data": { "id": "123", "email": "test@example.com" } }
调用parseUserInfo即可正确反序列化为GenericValue<UserInfo>实例。
内容的提问来源于stack exchange,提问作者RyanKing
相关产品推荐
相关产品推荐

