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
相关产品推荐
相关产品推荐

