返回

Flutter Dart 中处理 JSON 空字符串的巧妙方法

Android

使用 JSON 库解析 JSON 中空字符串的巧妙方法

引言

在 Flutter Dart 中使用 json_serializable 处理 JSON 数据时,您可能会遇到以下情况:JSON 中的某个字段可能包含空字符串,而您期望该字段为布尔类型。这会引起令人头疼的类型转换异常,阻碍您从 JSON 中提取数据。

问题

为了更好地理解问题,让我们来看一个示例 JSON 响应:

{
  "id": 3,
  "retro": ""
}

在我们的 Dart 模型中,我们有一个 retro 字段,期望它是一个布尔值。但是,由于 API 响应中 retro 字段是一个空字符串,因此解析器会抛出一个类型转换异常。

解决方案

为了解决这个问题,我们需要自定义 JSON 序列化和反序列化过程,以便将空字符串解析为布尔值。我们可以使用 @JsonKey 注解来实现此目的。

强制转换为布尔类型

以下是如何使用 _retroFromJson 函数将空字符串强制转换为布尔值的代码片段:

@JsonKey(fromJson: _retroFromJson)
bool? get retro => this.retro;

static bool? _retroFromJson(dynamic value) {
  if (value == null || value.toString().isEmpty) {
    return null;
  } else {
    return value as bool;
  }
}
  • _retroFromJson 函数 :检查 value 是否为空或为空字符串。如果是,则返回 null;否则,将其转换为布尔值。

反向转换

为了将 retro 字段从布尔值转换为字符串,以便将其序列化为 JSON,我们可以使用 _retroToJson 函数:

static String _retroToJson(bool? value) {
  if (value == null) {
    return "";
  } else {
    return value.toString();
  }
}
  • _retroToJson 函数 :检查 value 是否为空。如果是,则返回空字符串;否则,将其转换为字符串。

完整代码

以下是包含 _retroFromJson_retroToJson 函数的完整 Dart 模型:

import 'package:json_annotation/json_annotation.dart';

@JsonSerializable()
class UserItem {
  // 省略其他字段

  @JsonKey(name: 'retro')
  bool? retro;

  // ...

  @JsonKey(fromJson: _retroFromJson, toJson: _retroToJson)
  bool? get retro => this.retro;

  static bool? _retroFromJson(dynamic value) {
    // ...
  }

  static String _retroToJson(bool? value) {
    // ...
  }
}

优势

这种方法的好处在于它可以优雅地处理空字符串,而不会抛出类型转换异常。它还使您能够自定义 JSON 序列化和反序列化过程,从而为您的特定需求提供灵活性。

结论

通过使用 @JsonKey 注解中的 fromJsontoJson 参数,您可以轻松处理具有空字符串或其他类型转换问题的 JSON 数据。这将使您能够顺利解析 JSON 并从中提取所需的数据。

常见问题解答

  1. 这种方法是否仅适用于布尔类型?

    • 不,它可以应用于任何类型,例如字符串、数字和枚举。
  2. 为什么需要自定义反序列化和序列化过程?

    • 自定义过程允许您根据特定需求修改 JSON 数据的格式。
  3. @JsonKey 注解中其他有用的参数是什么?

    • name:指定 JSON 中字段的名称。
    • ignore:忽略特定字段。
    • defaultValue:如果 JSON 中没有该字段,则设置默认值。
  4. 使用这种方法有什么限制?

    • 这种方法依赖于 json_serializable 库。
  5. 是否有其他方法可以处理空字符串?

    • 可以使用 null safety 功能,其中 null 是允许的,但需要额外处理。