我想将我的Map编码为json。它看起来像这样:
Map<MyEnum, int> map = {type: limit};
其中 MyEnum
是枚举。一个简单的json.encode(map)
将不起作用,因为它不知道如何序列化枚举类。
错误消息是:
Unhandled Exception: Converting object to an encodable object failed: _LinkedHashMap len:1
如何将此地图序列化为json?
您可以在枚举上创建一个扩展名以将其转换为字符串,然后将地图转换为地图
import 'dart:convert';
enum MyEnum { type }
extension MyEnumModifier on MyEnum {
String get string => this.toString().split('.').last;
}
void main() {
Map<MyEnum, int> map = {MyEnum.type: 10};
Map<String, int> newMap = {};
map.forEach((key, value) =>
newMap[key.string] = value);
final json = jsonEncode(newMap);
print(json);
}
输出
{"type":10}
这真的不是一个我会推荐的解决方案,但我最终这么做主要是为了“好玩”。我不保证任何关于解决方案的事情,除了它是可怕的事实。:)
问题是enum
没有定义为Json的有效类型,因此整个概念确实给我们带来了一些问题。一种解决方案是将enum
值转换为字符串
,首先使用enum的名称,然后使用值的名称,如MyFirstEnum.first1
。如果对枚举
值调用toString()
,Dart会给出这种表示。
这很好,但为了安全起见,我们还可以在开头添加一个魔术字符串,如<code>DART_ENUM:MyFirstEnum。first1以便更容易在其他字符串之间识别,这些字符串可能与enum
value具有相同的名称,而不是enum。
接下来是类型安全。在Json中,我们知道所有的映射都有< code>String作为键的类型。通过制作我们自己的< code>enum表示并允许它也是键,我们不能期望解码器返回例如< code>Map
也就是说,我尝试构建一个Json解码器和编码器来处理< code>enum值。它还适用于地图中的< code>enum键:
import 'dart:convert';
class JsonConverterWithEnumSupport {
final String magicString;
final Set<Object> allEnumValues = {};
final Map<String, Object> enumStringToEnumValue = {};
JsonConverterWithEnumSupport(List<List<Object>>? enumsValues,
{this.magicString = "DART_ENUM:"}) {
enumsValues?.forEach(addEnumValues);
}
void addEnumValues(List<Object> enumValues) {
for (final enumValue in enumValues) {
enumStringToEnumValue[enumValue.toString()] = enumValue;
allEnumValues.add(enumValue);
}
}
String _addMagic(dynamic enumValue) => '$magicString$enumValue';
String _removeMagic(String string) => string.substring(magicString.length);
String encode(Object? value) =>
json.encode(value, toEncodable: (dynamic object) {
if (object is Map) {
return object.map<dynamic, dynamic>((dynamic key, dynamic value) =>
MapEntry<dynamic, dynamic>(
allEnumValues.contains(key) ? _addMagic(key) : key,
allEnumValues.contains(value) ? _addMagic(value) : value));
}
if (object is List) {
return object.map<dynamic>(
(dynamic e) => allEnumValues.contains(e) ? _addMagic(e) : e);
}
if (allEnumValues.contains(object)) {
return _addMagic(object);
}
return object;
});
dynamic decode(String source) => json.decode(source, reviver: (key, value) {
if (value is String && value.startsWith(magicString)) {
return enumStringToEnumValue[_removeMagic(value)];
}
if (value is Map) {
return value.map<dynamic, dynamic>((dynamic key, dynamic value) =>
MapEntry<dynamic, dynamic>(
(key is String) && key.startsWith(magicString)
? enumStringToEnumValue[_removeMagic(key)]
: key,
value));
}
return value;
});
}
enum MyFirstEnum { first1, first2 }
enum MySecondEnum { second1, second2 }
void main() {
final converter =
JsonConverterWithEnumSupport([MyFirstEnum.values, MySecondEnum.values]);
final jsonString = converter.encode({
MyFirstEnum.first1: [MySecondEnum.second2, MySecondEnum.second1],
'test': {MyFirstEnum.first2: 5}
});
print(jsonString);
// {"DART_ENUM:MyFirstEnum.first1":["DART_ENUM:MySecondEnum.second2","DART_ENUM:MySecondEnum.second1"],"test":{"DART_ENUM:MyFirstEnum.first2":5}}
print(converter.decode(jsonString));
// {MyFirstEnum.first1: [MySecondEnum.second2, MySecondEnum.second1], test: {MyFirstEnum.first2: 5}}
}
您将需要输入到 JsonConverter
中支持所有可能的枚举
值(例如,请参阅底部的主
方法)。
如果您不希望将魔术字符串附加到每个枚举上,
则只需创建带有以下参数的 JsonConverter
与以下工具进行支持:魔术字符串:'“
作为参数。
你可以在foundation.dart中使用dealEnum方法
我需要将Java转换为的实例(包括映射内容) 我应该用什么来代替来使此代码可编译?
问题内容: 我有以下JSON表示盐请求的服务器响应: 我尝试使用以下POJO映射它: 现在每次我这样做: 该为空。如何使用Gson将JSON映射到POJO?我的变量顺序对Gson映射重要吗? 问题答案: 我的变量顺序对Gson映射重要吗? 不,不是这样。 如何使用Gson将JSON映射到POJO? 它是 区分大小写 和JSON字符串键应该是相同的POJO类使用的变量名。 您可以使用@Seriali
我有以下JSON来表示salt请求的服务器响应: 我尝试用以下POJO映射它: 每次我这样做: 为空。如何使用GSON将JSON映射到POJO?变量的顺序对Gson映射重要吗?
我知道如何变换
问题内容: 我有一个主枚举类,它本质上是一种对象类型的类定义。例如,它看起来像下面的示例: 我正在尝试建立一个Javascript模型的发布请求,该请求在主体中发送一个映射,例如 到使用 而我得到以下错误信息: 不能建立从字符串“红”型ColorDefinition的地图键:不是一个有效的表示:不能建立从字符串“红”型ColorDefinition的地图键:对于Enum类值不是一个 什么我在这里做
我有4张桌子: 库存(库存ID、可用数量) 一个客户可以有多个订单,而一个订单由多个orderDetails项目组成。我正在尝试将库存项目存储在由库存项目和数量整数组成的映射中。 当我尝试以这种方式持久化它时,第一个库存项目将以1的orderID添加到Order详细信息表中。但是下一个是使用2的orderID插入的(不存在)。 有什么帮助吗?