Dart/Flutter中jsonDecode解析Java Long丢失精度的解决方案咨询
在Dart中解析超大JSON数字避免精度丢失
方案1:利用jsonDecode的reviver参数全局处理
Dart内置的jsonDecode支持传入reviver回调函数,可在解析过程中拦截并修改每个键值对的结果。我们可以通过判断数值是否超过2^53-1(double类型能精确表示的最大整数),将这类超大数值转为BigInt或String,彻底避免精度丢失。
示例代码:
import 'dart:convert'; void main() { // 2^53 - 1,double类型可精确表示的最大整数 const maxSafeInteger = 9007199254740991; var jsonStr = '''{ "myList": [ { "longNum": 1234567890123401352 }, { "longNum": 1234567890123450168 }, { "longNum": 1234567890123452213 } ], "secondList": "Other stuff... Is regex an elegant solution to parse 1234567890123401352 here?" }'''; Map parsedData = jsonDecode(jsonStr, reviver: (key, value) { if (value is num) { // 判断数值是否超出安全整数范围 if (value > maxSafeInteger || value < -maxSafeInteger) { // 转为BigInt保留精度,也可替换为value.toString()转成字符串 return BigInt.parse(value.toString()); } } return value; }); print(parsedData['myList'][0]['longNum']); // 精确输出:1234567890123401352 }
方案2:结合模型类与自定义转换器(适合结构化数据)
如果你的JSON有明确的业务结构,推荐使用json_serializable库配合自定义转换器,精准控制指定字段的解析逻辑,代码更易维护。
步骤1:定义转换器
import 'package:json_annotation/json_annotation.dart'; class BigIntConverter implements JsonConverter<BigInt, num> { const BigIntConverter(); @override BigInt fromJson(num json) => BigInt.parse(json.toString()); @override num toJson(BigInt object) => object.toInt(); // 若后端需接收字符串,可改为object.toString() }
步骤2:编写模型类
part 'data_model.g.dart'; @JsonSerializable() class ListItem { // 给需要解析为BigInt的字段添加转换器注解 @BigIntConverter() final BigInt longNum; ListItem({required this.longNum}); factory ListItem.fromJson(Map<String, dynamic> json) => _$ListItemFromJson(json); Map<String, dynamic> toJson() => _$ListItemToJson(this); } @JsonSerializable() class DataModel { final List<ListItem> myList; final String secondList; DataModel({required this.myList, required this.secondList}); factory DataModel.fromJson(Map<String, dynamic> json) => _$DataModelFromJson(json); Map<String, dynamic> toJson() => _$DataModelToJson(this); }
步骤3:使用模型解析
import 'dart:convert'; import 'data_model.dart'; void main() { var jsonStr = '''{...}'''; // 你的目标JSON字符串 var decodedJson = jsonDecode(jsonStr); var dataModel = DataModel.fromJson(decodedJson); print(dataModel.myList[0].longNum); // 精确输出原始数值 }
避坑提醒
- 禁止用正则解析JSON字符串:JSON结构可能包含嵌套、字符串内的数字等复杂场景,正则极易误处理,引发难以排查的bug。
- 若选择转为
String,后续使用时需手动处理类型转换;BigInt支持直接进行数值运算,灵活性更高。
内容的提问来源于stack exchange,提问作者jcpax
相关产品推荐
相关产品推荐

