Flutter/Dart JSON 和现有库类的序列化

Posted

技术标签:

【中文标题】Flutter/Dart JSON 和现有库类的序列化【英文标题】:Flutter/Dart JSON and serialization of an existing library class 【发布时间】:2020-04-30 03:58:29 【问题描述】:

我有一堂课:

import 'package:google_maps_flutter/google_maps_flutter.dart';

class Place 
  Place(
    this.address,
    this.coordinates,
  );

  final String address;
  final LatLng coordinates;

LatLng 是 google_maps_flutter 的一个类。如何使用json_annotationjson_serializable 使我的Place 类可序列化?

非常感谢!

【问题讨论】:

【参考方案1】:

我没有找到一个超级简单的解决方案。最后,我为 LatLng 属性编写了一个自定义 toJson/fromJson。我已将它静态地放到我的模型中,但如果您需要重用它,您也可以创建一个全局函数。

请注意,在我的示例中,LatLng 可以为空。

import 'dart:collection';
import 'dart:convert';

import 'package:latlong2/latlong.dart';

part 'challenge_model.g.dart';

@JsonSerializable()
class ChallengeModel with _$ChallengeModel 
  ChallengeModel(
    required this.startPosition,
  );

  @override
  @JsonKey(fromJson: latLngFromJson, toJson: latLngToJson)
  final LatLng? startPosition;

  /// Create [ChallengeModel] from a json representation
  static fromJson(Map<String, dynamic> json) => _$ChallengeModelFromJson(json);

  /// Json representation
  @override
  Map<String, dynamic> toJson() => _$ChallengeModelToJson(this);

  static String latLngToJson(LatLng? latLng) =>
      jsonEncode(latLng != null ? 'latitude': latLng.latitude, 'longitude': latLng.longitude : null);

  static LatLng? latLngFromJson(String jsonString) 
    final LinkedHashMap<String, dynamic>? jsonMap = jsonDecode(jsonString);

    return jsonMap != null ? LatLng(jsonMap['latitude'], jsonMap['longitude']) : null;
  


【讨论】:

【参考方案2】:

您可以使用 JsonKey 注解明确指定 LatLng 的哪些方法应该用于序列化:

@JsonSerializable()
class Place 
  Place(
    this.address,
    this.coordinates,
  );

  final String address;
  @JsonKey(fromJson: LatLng.fromJson, toJson: jsonEncode)
  final LatLng coordinates;

【讨论】:

这就是答案^【参考方案3】:

将此代码放入您的模型中

要从 JSON 响应中获取信息,只需在您的请求之后执行此操作

    最终位置 = placeFromJson(response.body); 获取地址 => = place.address 获取坐标 => place.coordinates.lng , place.coordinates.lat

==============================================


import 'dart:convert';

Place placeFromJson(String str) => Place.fromJson(json.decode(str));

String placeToJson(Place data) => json.encode(data.toJson());

class Place 
    String address;
    Coordinates coordinates;

    Place(
        this.address,
        this.coordinates,
    );

    factory Place.fromJson(Map<String, dynamic> json) => Place(
        address: json["address"],
        coordinates: Coordinates.fromJson(json["coordinates"]),
    );

    Map<String, dynamic> toJson() => 
        "address": address,
        "coordinates": coordinates.toJson(),
    ;


class Coordinates 
    String lat;
    String lng;

    Coordinates(
        this.lat,
        this.lng,
    );

    factory Coordinates.fromJson(Map<String, dynamic> json) => Coordinates(
        lat: json["lat"],
        lng: json["lng"],
    );

    Map<String, dynamic> toJson() => 
        "lat": lat,
        "lng": lng,
    ;

【讨论】:

谢谢!问题是我需要使用LatLng 类。我可以使用它并使我的Place 类可序列化吗?

以上是关于Flutter/Dart JSON 和现有库类的序列化的主要内容,如果未能解决你的问题,请参考以下文章

Flutter - 带有 Dart 的通用 json 序列化器

Flutter/Dart json 用特殊字符编码密码

Flutter Dart - 动态获取类的属性

在 Flutter/Dart 中从 JSON 数组中提取数据

如果 Flutter/Dart 中没有名称/键,如何序列化/解析嵌套的 JSON 数组

收到推送通知但未显示(Flutter / Dart)