如何在 Dart 中使用 json_annotation 将 Uint8List 序列化为 json?

Gue*_*OCs 13 json dart flutter

我创建了一个有Uint8List成员的简单类:

\n
import "package:json_annotation/json_annotation.dart";\npart "openvpn.g.dart";\n\n@JsonSerializable()\nclass OpenVPN extends VPN {\n  OpenVPN(Uint8List profile) {\n    this.profile = profile;\n  }\n  /...\n  Uint8List profile = null;\n
Run Code Online (Sandbox Code Playgroud)\n

但是,当在其上运行构建运行程序以生成 json 序列化程序时,我得到:

\n
Could not generate `fromJson` code for `profile`.\nNone of the provided `TypeHelper` instances support the defined type.\npackage:my_app/folder/openvpn.dart:19:13\n   \xe2\x95\xb7\n19 \xe2\x94\x82   Uint8List profile = null;\n   \xe2\x94\x82             ^^^^^^^\n
Run Code Online (Sandbox Code Playgroud)\n

有没有办法为这种类型编写自己的序列化器?或者有更简单的方法吗?\n我不想在 json 文件中包含字符串,我想要实际的字节。这是一个小文件,因此将字节数组存储在 json 中是有意义的。

\n

And*_*ija 17

首先,添加一个自定义 JSON 转换器Uint8List

import "dart:typed_data";

import "package:json_annotation/json_annotation.dart";

/// Converts to and from [Uint8List] and [List]<[int]>.
class Uint8ListConverter implements JsonConverter<Uint8List?, List<int>?> {
  /// Create a new instance of [Uint8ListConverter].
  const Uint8ListConverter();

  
  @override
  Uint8List? fromJson(List<int>? json) {
    if (json == null) return null;

    return Uint8List.fromList(json);
  }

  @override
  List<int>? toJson(Uint8List? object) {
    if (object == null) return null;

    return object.toList();
  }
Run Code Online (Sandbox Code Playgroud)

用于Uint8ListConverterUint8List 属性。在你的情况下:

import 'dart:typed_data';

import 'package:json_annotation/json_annotation.dart';

import 'uint8_list_converter.dart';

part 'open_vpn.g.dart';

@JsonSerializable(explicitToJson: true)
class OpenVPN {
  OpenVPN({this.profile});

  @Uint8ListConverter()
  Uint8List? profile = null;

  factory OpenVPN.fromJson(Map<String, Object?> json) =>
      _$OpenVPNFromJson(json);

  Map<String, Object?> toJson() => _$OpenVPNToJson(this);
}
Run Code Online (Sandbox Code Playgroud)

在项目根目录中,在终端中运行以下命令以生成open_vpn.g.dart零件文件:dart run build_runner build --delete-conflicting-outputs


Abi*_*n47 2

在您的OpenVPN序列化方法中,将 转换Uint8ListList<int>. 根据您的实现,它可能看起来像:

class OpenVPN {
  factory OpenVPN.fromJson(dynamic map) {
    return OpenVPN(
        ...
        profile: Uint8List.fromList(map['profile'] ?? []),
    );
  }

  toJson() {
    return {
      ...
      'profile': profile as List<int>,
    };
  }
}
Run Code Online (Sandbox Code Playgroud)