You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter json_serializable实现JSON解析映射及新旧字段兼容方案

Flutter 推荐板块JSON解析与字段兼容实现

前置依赖配置

首先在pubspec.yaml中添加所需依赖:

dependencies:
  flutter:
    sdk: flutter
  dio: ^最新稳定版
  json_annotation: ^最新稳定版

dev_dependencies:
  build_runner: ^最新稳定版
  json_serializable: ^最新稳定版

配置完成后执行flutter pub get安装依赖。

Model类定义与自动映射实现

共定义3层Model,完全匹配给定的JSON结构:

1. 单个健身房信息实体类(含字段兼容逻辑)

对应JSON中城市数组下的单个健身房对象,同时实现name字段的新旧键兼容:

import 'package:json_annotation/json_annotation.dart';

part 'gym_info.g.dart';

@JsonSerializable()
class GymInfo {
  @JsonKey(name: 'gym_id')
  final String gymId;

  // 配置新旧键兼容读取规则
  @JsonKey(readValue: _readNameValue)
  final String name;

  final String address;
  @JsonKey(name: 'city_id')
  final String cityId;
  @JsonKey(name: 'gym_logo')
  final String gymLogo;
  @JsonKey(name: 'no_of_ratings')
  final String? noOfRatings;
  @JsonKey(name: 'total_ratings')
  final String? totalRatings;
  @JsonKey(name: 'average_ratings')
  final String? averageRatings;
  @JsonKey(name: 'city_name')
  final String cityName;

  GymInfo({
    required this.gymId,
    required this.name,
    required this.address,
    required this.cityId,
    required this.gymLogo,
    this.noOfRatings,
    this.totalRatings,
    this.averageRatings,
    required this.cityName,
  });

  factory GymInfo.fromJson(Map<String, dynamic> json) => _$GymInfoFromJson(json);
  Map<String, dynamic> toJson() => _$GymInfoToJson(this);

  // 自定义字段读取逻辑:优先读新键name,不存在则读旧键aStupidName
  static Object? _readNameValue(Map json, String key) {
    return json['name'] ?? json['aStupidName'];
  }
}

2. 推荐板块内容实体类

对应JSON中data字段的动态结构(键为城市名,值为对应城市的健身房列表):

import 'package:json_annotation/json_annotation.dart';
import 'gym_info.dart';

part 'recommended_data.g.dart';

@JsonSerializable()
class RecommendedData {
  final Map<String, List<GymInfo>> cityGymMap;

  RecommendedData({required this.cityGymMap});

  factory RecommendedData.fromJson(Map<String, dynamic> json) {
    final parsedMap = json.map((cityName, gymList) {
      return MapEntry(
        cityName,
        (gymList as List).map((e) => GymInfo.fromJson(e as Map<String, dynamic>)).toList(),
      );
    });
    return RecommendedData(cityGymMap: parsedMap);
  }

  Map<String, dynamic> toJson() {
    return cityGymMap.map((cityName, gymList) {
      return MapEntry(cityName, gymList.map((e) => e.toJson()).toList());
    });
  }
}

3. 推荐板块最外层实体类

对应recommended字段的完整结构:

import 'package:json_annotation/json_annotation.dart';
import 'recommended_data.dart';

part 'recommended_section.g.dart';

@JsonSerializable()
class RecommendedSection {
  @JsonKey(name: 'section_title')
  final String sectionTitle;
  @JsonKey(name: 'section_sub_title')
  final String sectionSubTitle;
  final RecommendedData data;

  RecommendedSection({
    required this.sectionTitle,
    required this.sectionSubTitle,
    required this.data,
  });

  factory RecommendedSection.fromJson(Map<String, dynamic> json) => _$RecommendedSectionFromJson(json);
  Map<String, dynamic> toJson() => _$RecommendedSectionToJson(this);
}

Dio响应自动映射配置

编写通用解析方法,配合Dio请求逻辑实现响应数据自动转Model:

import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';

/// 推荐板块接口响应解析方法
RecommendedSection? parseRecommendedResponse(Response response) {
  if (response.statusCode == 200 && response.data is Map) {
    try {
      final recommendedJson = response.data['recommended'] as Map<String, dynamic>;
      return RecommendedSection.fromJson(recommendedJson);
    } catch (e) {
      debugPrint('推荐板块JSON解析失败: $e');
      return null;
    }
  }
  return null;
}

// 接口调用示例
void fetchRecommendedGyms() async {
  final dio = Dio();
  final res = await dio.get('对应业务接口地址');
  final recommendedData = parseRecommendedResponse(res);
  // 后续直接操作recommendedData对象即可
}

序列化代码生成

写完所有Model类后,在项目根目录执行以下命令,自动生成json_serializable对应的序列化/反序列化代码:
flutter pub run build_runner build --delete-conflicting-outputs

兼容逻辑说明:上述GymInfo类中的自定义读值方法已实现版本向下兼容,不管是新接口返回的name字段,还是旧版本本地缓存、老接口返回的aStupidName字段,都能正确读取赋值,不会出现字段解析为空的问题。

内容的提问来源于stack exchange,提问作者Arun99178

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 12:24:23