ネストされた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"という名前のコンストラクタがないため、明らかに最後の行でエラーがスローされます。タイプにいくつかの制限を追加してみましたが、解決策は見つかりませんでした。これをどのようにやってのけるかについて何か考えがありますか?
あなたはそのようなことはできません。少なくとも羽ばたきはできません。なので Dart:mirror
は無効であり、クラスコンストラクターのインターフェイスはありません。
別のルートを取る必要があります。
代わりにPOOを使用することをお勧めします。ここでは、responseObject
からBaseResponse
をデシリアライズすることをあきらめます。そして、BaseResponse
のサブクラスがこの逆シリアル化を処理します
通常、タイプごとに1つのサブクラスがあります。
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"});
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)])
);
世話をする必要がある定型文がもう1つあります。 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