2 回答
TA贡献1836条经验 获得超3个赞
因为文档没有充分涵盖这一点,所以我花了一天时间研究颤动源和不同事物的反复试验来解决它。所以不妨分享一下。
Golang 默认情况下在序列化为 Json 时在 RFC3339 中编码 time.Time(如在给定的示例中)。Flutter 明确支持 RFC3339,为什么它不起作用?答案是秒小数部分的支持方式略有不同。虽然 Golang 产生 7 位数字的精度,但 Dart 最多只支持 6 位数字并且不会优雅地处理违规情况。因此,如果将示例更正为只有 6 位精度,它将在 Dart 中解析得很好:
{
...
"dateCreated": "2018-09-29T19:51:57.413978-07:00",
...
}
为了以通用的方式解决这个问题,您有两个选择:1. 从字符串中截断额外的精度,或者 2. 实现您自己的解析。假设我们扩展DateTime类并创建您自己的CustomDateTime. 新类重写了parse方法,在将其交给父类的解析方法之前删除 6 位数字后的所有多余部分。
现在我们可以在我们的 Dart 类中使用了CustomDateTime。例如:
@JsonSerializable()
class MyObj {
CustomDateTime dateCreated;
MyObj( this.dateCreated);
factory MyObj.fromJson(Map<String, dynamic> json) => _$MyObjFromJson(json);
Map<String, dynamic> toJson() => _$MyObjToJson(this);
}
但是当然现在代码生成被破坏了,我们得到以下错误:
Error running JsonSerializableGenerator
Could not generate 'toJson' code for 'dateCreated'.
None of the provided 'TypeHelper' instances support the defined type.
幸运的是,该json_annotation软件包现在为我们提供了一个简单的解决方案 - The JsonConverter. 以下是如何在我们的示例中使用它:
首先定义一个转换器,向代码生成器解释如何转换我们的CustomDateTime类型:
class CustomDateTimeConverter implements JsonConverter<CustomDateTime, String> {
const CustomDateTimeConverter();
@override
CustomDateTime fromJson(String json) =>
json == null ? null : CustomDateTime.parse(json);
@override
String toJson(CustomDateTime object) => object.toIso8601String();
}
其次,我们只是将此转换器注释为使用我们的 CustomDateTime 数据类型的每个类:
@JsonSerializable()
@CustomDateTimeConverter()
class MyObj {
CustomDateTime dateCreated;
MyObj( this.dateCreated);
factory MyObj.fromJson(Map<String, dynamic> json) => _$MyObjFromJson(json);
Map<String, dynamic> toJson() => _$MyObjToJson(this);
}
这满足了代码生成器和 Voila!我们可以读取带有来自 golang time.Time 的 RFC3339 时间戳的 json。
TA贡献1818条经验 获得超3个赞
我有同样的问题。我找到了一个非常简单的解决方案。我们可以使用带有 JsonConverter 的自定义转换器。
import 'package:json_annotation/json_annotation.dart';
class CustomDateTimeConverter implements JsonConverter<DateTime, String> {
const CustomDateTimeConverter();
@override
DateTime fromJson(String json) {
if (json.contains(".")) {
json = json.substring(0, json.length - 1);
}
return DateTime.parse(json);
}
@override
String toJson(DateTime json) => json.toIso8601String();
}
import 'package:json_annotation/json_annotation.dart';
import 'package:my_app/shared/helpers/custom_datetime.dart';
part 'publication_document.g.dart';
@JsonSerializable()
@CustomDateTimeConverter()
class PublicationDocument {
final int id;
final int publicationId;
final DateTime publicationDate;
final DateTime createTime;
final DateTime updateTime;
final bool isFree;
PublicationDocument({
this.id,
this.publicationId,
this.publicationDate,
this.createTime,
this.updateTime,
this.isFree,
});
factory PublicationDocument.fromJson(Map<String, dynamic> json) =>
_$PublicationDocumentFromJson(json);
Map<String, dynamic> toJson() => _$PublicationDocumentToJson(this);
}
- 2 回答
- 0 关注
- 204 浏览
添加回答
举报