如果您觉得文章对您有帮助,欢迎 👍, 我的 Github.
调试josn bean序列化时,发现下面这个错误:
════════ Exception caught by gesture ═══════════════════════
The following _CastError was thrown while handling a gesture:
type 'String' is not a subtype of type 'int' in type cast
When the exception was thrown, this was the stack:
#0 _$DemoBeanFromJson (package:zmusic/test.g.dart:11:35)
#1 new DemoBean.fromJson (package:zmusic/test.dart:13:7)
#2 _MyHomePageState.build.<anonymous closure> (package:zmusic/main.dart:36:20)
#3 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:772:19)
#4 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:855:36)
...
使用的是json_serializable序列化json, 写了个demo复现了下:
test:
DemoBean.fromJson(jsonDecode('{"intField":"123","stringField":"123"}'));
import 'package:json_annotation/json_annotation.dart';
part 'test.g.dart';
@JsonSerializable()
class DemoBean {
int intField;
String stringField;
DemoBean();
factory DemoBean.fromJson(Map<String, dynamic> json) =>
_$DemoBeanFromJson(json);
Map<String, dynamic> toJson() => _$DemoBeanToJson(this);
}
.g.dart:
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'test.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
DemoBean _$DemoBeanFromJson(Map<String, dynamic> json) {
return DemoBean()
..intField = json['intField'] as int //问题出在这里,json中是真实的数据类型,as时导致了crash
..stringField = json['stringField'] as String;//问题出在这里,json中是真实的数据类型,as时导致了crash
}
Map<String, dynamic> _$DemoBeanToJson(DemoBean instance) => <String, dynamic>{
'intField': instance.intField,
'stringField': instance.stringField,
};
问题出在 json['intField'] as int ,json中是真实的数据类型,as时导致了crash.
查了下文档,发现可以使用 @JsonKey(fromJson: xxx) 的fromJson参数对转换过程做hook。
调整bean代码:
import 'package:json_annotation/json_annotation.dart';
part 'test.g.dart';
@JsonSerializable()
class DemoBean {
@JsonKey(fromJson: _dynamicToInt)
int intField;
@JsonKey(fromJson: _dynamicToString)
String stringField;
DemoBean();
factory DemoBean.fromJson(Map<String, dynamic> json) =>
_$DemoBeanFromJson(json);
Map<String, dynamic> toJson() => _$DemoBeanToJson(this);
static _dynamicToInt(dynamic value) {
return value == null ? null : int.parse(value);
}
static _dynamicToString(dynamic value) {
return value == null ? null : value.toString();
}
}
.g.dart
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'test.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
DemoBean _$DemoBeanFromJson(Map<String, dynamic> json) {
return DemoBean()
..intField = DemoBean._dynamicToInt(json['intField'])
..stringField = DemoBean._dynamicToString(json['stringField']);
}
Map<String, dynamic> _$DemoBeanToJson(DemoBean instance) => <String, dynamic>{
'intField': instance.intField,
'stringField': instance.stringField,
};
DemoBean._dynamicToInt(json['intField']) 没有as逻辑,问题解决。