Dart json_serializable是否有内置跨类型JSON解码方案无需自定义方法
问题解答
json_serializable 没有提供完全免写转换逻辑的内置能力来自动将int/List<int>转成String/List<String>。出于类型安全考虑,它默认不会做隐式跨类型转换,所有类型不匹配的字段都需要显式声明转换规则。不过官方提供了比散写顶层转换函数更规整、复用性更强的标准实现方案,不需要额外依赖第三方包。
推荐方案:使用内置JsonConverter封装转换逻辑
这是json_serializable官方推荐的类型转换写法,尤其适合转换逻辑需要在多个字段、多个类复用的场景。你可以把同类型转换规则统一封装在转换器类中,避免全局散落零散的转换函数:
// 通用int转String转换器 class Int2StringConverter implements JsonConverter<String, int> { const Int2StringConverter(); @override String fromJson(int json) => json.toString(); @override int toJson(String object) => int.parse(object); } // 通用int列表转String列表转换器 class IntList2StringListConverter implements JsonConverter<List<String>, List<dynamic>> { const IntList2StringListConverter(); @override List<String> fromJson(List<dynamic> json) => json.map((e) => e.toString()).toList(); @override List<dynamic> toJson(List<String> object) => object.map(int.parse).toList(); }
使用时既可以直接注解在单个字段上,也可以注解在类上,自动应用到类内所有匹配类型的字段:
@JsonSerializable() @Int2StringConverter() @IntList2StringListConverter() class Example { String a; List<String> b; Example(this.a, this.b); factory Example.fromJson(Map<String, dynamic> json) => _$ExampleFromJson(json); Map<String, dynamic> toJson() => _$ExampleToJson(this); }
轻量场景简化写法
如果转换逻辑只在当前类使用、不需要复用,你可以直接把转换逻辑收敛为类内的私有静态方法,不用单独抽离全局函数,也不用额外定义转换器类,比现有写法更整洁:
@JsonSerializable() class Example { @JsonKey(fromJson: _int2Str) String a; @JsonKey(fromJson: _intList2StrList) List<String> b; Example(this.a, this.b); static String _int2Str(int val) => val.toString(); static List<String> _intList2StrList(List<dynamic> val) => val.map((e) => e.toString()).toList(); factory Example.fromJson(Map<String, dynamic> json) => _$ExampleFromJson(json); Map<String, dynamic> toJson() => _$ExampleToJson(this); }
注意:不建议依赖框架的隐式类型转换能力。这类跨基础类型的转换本身存在边界风险(比如int转String是安全的,但反向转换时可能遇到非数字内容报错),显式声明转换逻辑更方便你统一处理异常场景。
内容的提问来源于stack exchange,提问作者Koren Minchev
相关产品推荐
相关产品推荐

