Flutter如何实现泛型转JSON

在Flutter中,如何实现泛型对象的JSON序列化和反序列化?比如有一个泛型类Response<T>,想将T类型的数据自动转换为JSON或从JSON解析回来。使用jsonEncodejsonDecode时,如何处理泛型类型T的转换?是否需要为每种T类型单独实现toJsonfromJson方法,还是有更通用的解决方案?

2 回复

Flutter中可使用json_serializable库配合build_runner自动生成泛型转JSON代码。需在类上添加@JsonSerializable(genericArgumentFactories: true)注解,并手动编写fromJsontoJson方法处理泛型类型。

更多关于Flutter如何实现泛型转JSON的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中实现泛型转JSON,可以通过以下几种方式:

1. 使用json_serializable(推荐)

首先在pubspec.yaml添加依赖:

dependencies:
  json_annotation: ^4.8.1

dev_dependencies:
  json_serializable: ^6.7.1
  build_runner: ^2.4.6

创建泛型模型类:

import 'package:json_annotation/json_annotation.dart';

part 'api_response.g.dart';

@JsonSerializable(genericArgumentFactories: true)
class ApiResponse<T> {
  final int code;
  final String message;
  final T? data;

  ApiResponse({
    required this.code,
    required this.message,
    this.data,
  });

  factory ApiResponse.fromJson(
    Map<String, dynamic> json,
    T Function(Object? json) fromJsonT,
  ) =>
      _$ApiResponseFromJson(json, fromJsonT);

  Map<String, dynamic> toJson(Object? Function(T value) toJsonT) =>
      _$ApiResponseToJson(this, toJsonT);
}

运行代码生成:

flutter pub run build_runner build

使用示例:

// 用户模型
@JsonSerializable()
class User {
  final String name;
  final int age;
  
  User({required this.name, required this.age});
  
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

// 使用泛型响应
void main() {
  final json = {
    'code': 200,
    'message': 'success',
    'data': {'name': 'John', 'age': 25}
  };
  
  final response = ApiResponse<User>.fromJson(
    json, 
    (json) => User.fromJson(json as Map<String, dynamic>)
  );
  
  print(response.data?.name); // 输出: John
}

2. 手动实现泛型序列化

class GenericResponse<T> {
  final T? data;
  
  GenericResponse({this.data});
  
  factory GenericResponse.fromJson(
    Map<String, dynamic> json, 
    T Function(Map<String, dynamic>) fromJson,
  ) {
    return GenericResponse<T>(
      data: fromJson(json['data']),
    );
  }
  
  Map<String, dynamic> toJson(Map<String, dynamic> Function(T) toJson) {
    return {
      'data': data != null ? toJson(data!) : null,
    };
  }
}

主要要点:

  • 使用json_serializablegenericArgumentFactories参数支持泛型
  • 在fromJson/toJson方法中传递类型转换函数
  • 运行build_runner生成序列化代码

这种方式可以保持类型安全,同时支持任意类型的泛型参数。

回到顶部