Flutter中如何解密JSON并创建带动态键的POJO类?
Flutter 处理带动态键的 JSON 模型创建方案
先拿常见的动态键JSON结构举例子(如果你的实际解密后结构不一样,直接替换就行):
解密后的JSON示例:
{ "dynamic_key_1": { "id": 1, "title": "内容1" }, "dynamic_key_2": { "id": 2, "title": "内容2" } }
这里最外层的键(dynamic_key_1、dynamic_key_2)是动态变化的,没法提前固定写死在类里,下面给你两种实用的处理方式:
1. 手动编写模型(无依赖)
第一步:先写固定结构的子模型
动态键对应的内部值结构是固定的,先把这部分写成普通Dart类:
class Item { final int id; final String title; Item({required this.id, required this.title}); // 从JSON转模型 factory Item.fromJson(Map<String, dynamic> json) { return Item( id: json['id'] as int, title: json['title'] as String, ); } // 模型转JSON(用不到可以删) Map<String, dynamic> toJson() { return { 'id': id, 'title': title, }; } }
第二步:用Map接收动态键
不需要额外写外层类,直接用Map<String, Item>来接收整个JSON对象:
// 把解密后的JSON字符串转成原始Map String decryptedJson = "你的解密后JSON字符串"; Map<String, dynamic> rawJson = jsonDecode(decryptedJson); // 遍历转成带类型的Map Map<String, Item> dynamicItemMap = rawJson.map( (key, value) => MapEntry(key, Item.fromJson(value as Map<String, dynamic>)), );
2. 用json_serializable简化(推荐)
如果JSON结构复杂,或者不想手动写解析逻辑,可以用官方推荐的json_serializable库:
第一步:添加依赖
在pubspec.yaml里加:
dependencies: json_annotation: ^4.8.1 dev_dependencies: build_runner: ^2.4.4 json_serializable: ^6.7.1
然后执行flutter pub get安装。
第二步:写模型类
import 'package:json_annotation/json_annotation.dart'; part 'item.g.dart'; @JsonSerializable() class Item { final int id; final String title; Item({required this.id, required this.title}); factory Item.fromJson(Map<String, dynamic> json) => _$ItemFromJson(json); Map<String, dynamic> toJson() => _$ItemToJson(json); } // 要是想把外层动态键也封装成类,可以写这个 @JsonSerializable() class DynamicData { final Map<String, Item> items; DynamicData({required this.items}); factory DynamicData.fromJson(Map<String, dynamic> json) => _$DynamicDataFromJson(json); Map<String, dynamic> toJson() => _$DynamicDataToJson(json); }
第三步:生成解析代码
在终端运行命令:
flutter pub run build_runner build
会自动生成item.g.dart文件,包含自动生成的解析逻辑。
第四步:解析JSON
String decryptedJson = "你的解密后JSON字符串"; Map<String, dynamic> rawJson = jsonDecode(decryptedJson); // 要是用了封装类 DynamicData data = DynamicData.fromJson(rawJson); // 直接用Map的话就和之前一样 Map<String, Item> itemMap = rawJson.map((k, v) => MapEntry(k, Item.fromJson(v)));
嵌套更深的动态键处理
如果你的JSON是多层嵌套的动态键,比如:
{ "month_data": { "202405": [ {"id":1, "name":"A"}, {"id":2, "name":"B"} ], "202406": [ {"id":3, "name":"C"} ] } }
那外层模型可以这么写:
@JsonSerializable() class MonthDataWrapper { final Map<String, List<Item>> monthData; MonthDataWrapper({required this.monthData}); factory MonthDataWrapper.fromJson(Map<String, dynamic> json) => _$MonthDataWrapperFromJson(json); }
生成代码后直接解析就行,原理都是用Map<String, T>来承载动态键,T是对应值的类型(可以是类、列表、基本类型)。
注意点
- 确保解密后的JSON格式正确,没有语法错误,不然解析会报错;
- 如果动态键对应的值结构不固定,那只能用
Map<String, dynamic>来接收,但尽量保证值的结构统一,方便后续处理; - 类型转换的时候注意空安全,比如用
json['id'] as int?代替as int,避免空值崩溃。
内容的提问来源于stack exchange,提问作者Vickey Rajak
相关产品推荐
相关产品推荐

