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

Flutter中如何处理API同一Key对应多种数据类型的问题?

在Flutter中处理API返回JSON同一字段多类型的问题

针对你遇到的offer_price字段同时存在整数、浮点数、字符串、null多种类型的情况,核心目标是把这些不同类型统一转换成可空的double类型(double?),下面提供两种实用的处理方案:

方案一:手动解析JSON(无需依赖序列化库)

适合小型项目或不想引入第三方库的场景,直接在实体类的fromJson工厂方法中自定义解析逻辑:

class Product {
  final int id;
  final double price;
  final double? offerPrice;

  Product({
    required this.id,
    required this.price,
    this.offerPrice,
  });

  factory Product.fromJson(Map<String, dynamic> json) {
    return Product(
      id: json['id'] as int,
      price: json['price'] as double,
      offerPrice: _parseOfferPrice(json['offer_price']),
    );
  }

  // 核心解析方法:处理多种类型的offer_price
  static double? _parseOfferPrice(dynamic value) {
    if (value == null) return null;
    if (value is int) return value.toDouble(); // 整数转double
    if (value is double) return value; // 直接返回浮点数
    if (value is String) {
      return double.tryParse(value); // 字符串尝试转double,失败返回null
    }
    // 遇到未知类型时,可返回null或根据业务抛出异常
    return null;
  }
}

使用示例(解析整个API响应):

import 'dart:convert';

// 假设response是API请求返回的响应对象
final Map<String, dynamic> responseJson = json.decode(response.body);
final List<Product> products = (responseJson['product'] as List)
    .map((item) => Product.fromJson(item as Map<String, dynamic>))
    .toList();

方案二:使用json_serializable自定义转换器

适合大型项目,借助成熟的序列化库统一管理解析逻辑,步骤如下:

1. 添加依赖

在pubspec.yaml中添加相关依赖:

dependencies:
  json_annotation: ^4.8.1

dev_dependencies:
  build_runner: ^2.4.4
  json_serializable: ^6.7.0

2. 定义自定义转换器

创建一个转换器类,专门处理offer_price的多类型解析:

import 'package:json_annotation/json_annotation.dart';

class OfferPriceConverter implements JsonConverter<double?, dynamic> {
  const OfferPriceConverter();

  @override
  double? fromJson(dynamic value) {
    if (value == null) return null;
    if (value is int) return value.toDouble();
    if (value is double) return value;
    if (value is String) {
      return double.tryParse(value);
    }
    return null;
  }

  @override
  dynamic toJson(double? value) => value; // 序列化时直接返回原double值,可按需调整
}

3. 在实体类中使用转换器

import 'package:json_annotation/json_annotation.dart';

part 'product.g.dart';

@JsonSerializable()
class Product {
  final int id;
  final double price;

  // 给offerPrice字段标记自定义转换器
  @OfferPriceConverter()
  final double? offerPrice;

  Product({
    required this.id,
    required this.price,
    this.offerPrice,
  });

  factory Product.fromJson(Map<String, dynamic> json) => _$ProductFromJson(json);
  Map<String, dynamic> toJson() => _$ProductToJson(this);
}

4. 生成序列化代码

在终端运行以下命令,自动生成product.g.dart文件:

flutter pub run build_runner build

注意事项

  • 若字符串类型的offer_price存在非数字内容(比如"abc"),double.tryParse会返回null,可根据业务需求修改为抛出异常或返回默认值(如0.0)。
  • 遇到未知类型时,建议添加日志输出,方便调试API返回的异常数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 00:55:22