我想知道如何将嵌套的json解析为具有通用类型的类。我的意图是用代码和消息包装来自后端的响应(例如包含令牌的loginRespose)
我有
class BaseResponse<T>{
int code;
String message;
T responseObject;
BaseResponse.fromJson(Map<String, dynamic> parsedJson)
: code = parsedJson['Code'],
message = parsedJson['Message'],
responseObject = T.fromJson(parsedJson['ResponseObject']); //This is what I'd like to do
}
很显然,最后一行引发错误,因为T没有命名构造函数“ fromJson”。 我尝试为Type添加一些限制,但是没有找到任何解决方案。您对如何实现此目标有任何想法吗?
答案 0 :(得分:7)
您不能做这种事情,至少不能动摇。由于dart:mirror
被禁用,并且类构造函数没有接口。
您必须采用其他路线。
我建议改为使用POO。您将在这里放弃从responseObject
反序列化BaseResponse
的过程。然后让BaseResponse
的子类处理反序列化
通常,每种类型只有一个子类:
class IntResponse extends BaseResponse<int> {
IntResponse.fromJson(Map<String, dynamic> json) : super._fromJson(json) {
this.responseObject = int.parse(json["Hello"]);
}
}
然后您可以通过在BaseResponse
上添加自定义工厂构造函数以使其更方便使用来隐藏此混乱情况。
class BaseResponse<T> {
int code;
String message;
T responseObject;
BaseResponse._fromJson(Map<String, dynamic> parsedJson)
: code = parsedJson['Code'],
message = parsedJson['Message'];
factory BaseResponse.fromJson(Map<String, dynamic> json) {
if (T == int) {
return IntResponse.fromJson(json) as BaseResponse<T>;
}
throw UnimplementedError();
}
}
然后直接实例化所需的类型,或使用工厂构造函数:
final BaseResponse foo = BaseResponse.fromJson<int>({"Hello": "42", "Code": 42, "Message": "World"});
答案 1 :(得分:2)
您可以使用built_value软件包来实现此目的(您还需要built_value_generator和build_runner)。您的课程如下所示:
part 'base_response.g.dart';
abstract class BaseResponse<T> implements Built<BaseResponse<T>, BaseResponseBuilder<T>> {
int code;
String message;
T responseObject;
factory BaseResponse([updates(BaseResponseBuilder<T> b)]) = _$BaseResponse<T>;
static Serializer<BaseResponse> get serializer => _$baseResponseSerializer;
}
您将必须运行flutter packages pub run build_runner build
来生成生成的文件。然后像这样使用它:
BaseResponse baseResponse = serializers.deserialize(
json.decode(response.body),
specifiedType: const FullType(BaseResponse, const [FullType(ConcreteTypeGoesHere)])
);
您只需要注意一点点样板即可。您需要另一个名为serializers.dart的文件。您需要在此处手动添加要反序列化的所有类,还需要为每个带有类型参数的类以及要使用的每种具体类型添加addBuilderFactory函数。
part 'serializers.g.dart';
@SerializersFor(const [
BaseResponse,
ConcreteTypeGoesHere,
])
final Serializers serializers = (_$serializers.toBuilder()
..addBuilderFactory(
FullType(BaseResponse, const [const FullType(ConcreteTypeGoesHere)]),
() => new BaseResponseBuilder<ConcreteTypeGoesHere>()
)
..addPlugin(StandardJsonPlugin()))
.build();
然后重新运行flutter packages pub run build_runner build
让我对Gson充满希望...:S