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 關注
- 297 瀏覽
添加回答
舉報