在同一个 JSON 中序列化两个对象,然后通过 Redis 从传入的字符串中反序列化它们
Serializing two objects within the same JSON and then deserializing them from the incoming string through Redis
我的开发团队在使用 jackson 时遇到了一些问题。
一些不重要的上下文
我们对 jackson 还很陌生,过去我们遇到过几个问题,但我们一直试图用我们从互联网上得到的东西来解决它们,并用过去的问题在 Whosebug 上解决。
有用信息
我们正在将 Java 实例化对象解析为 JSON,这样我们就可以将它们作为字符串通过 redis 发送,然后通过 pub/sub 系统将它们再次作为原始类型的对象再次获取结束。
我们有 2 个字段,每个字段代表不同的对象:
Data: a ChannelMessage object.
String senderName, message;
Enum:ServerType serverType;
Metadata: a RedisMetadata object.
String id, channelName, serverId;
Enum:MessageType type;
所以我们的 JSON 应该看起来像这样:
{
"data": {
"senderName": "PixelDev1729",
"message": "asd",
"serverType": "HUB"
},
"metadata": {
"id": "1bba40f5-74ed-4ab8-ad81-83078ac11421",
"channelName": "global-chat",
"serverId": "b4409522-6a97-47f5-ad75-661ed86c52e8",
"type": "SEND"
}
}
几个头疼
我们已经尝试使用 ObjectNodes 从对象中将值写入字符串。
我们得到了一个非常混乱的 JSON 字符串,其中有很多转义符(反斜杠)。
{"data":"{\"senderName\":\"PixelDev1729\",\"message\":\"asd\",\"serverType\":\"HUB\"}","metadata":"{\"id\":\"e0f77d09-cafa-4ff5-b553-0f0dc4bb76e3\",\"cha|
nnelName":"global-chat","serverId":"9f10cf0b-d3eb-4804-98aa-92d747d75f5e","type":"SEND"}"}
- “没有字符串参数 constructor/factory 方法从字符串值反序列化(列:1,行:1)。”根据我的专业知识,我可以说 Jackson 得到的 JSON 字符串无效。
如此不同的方法...
将 jsonString.replaceAll("^\"|\"$|\\", "");
用于我们首先得到的相同字符串。
结果几乎有效 JSON 但仍然无效,因为我们缺少一些双引号。
{"data":"{"senderName":"wasmake","message":"sadasdas","serverType":"VALHEIM"}","元数据":"{"id":"410c429c-06a4-466a-bce2-5edd63fabe17",|
"channelName":"global-chat","serverId":"640d01c3-5b13-4dcf-84bc-1d6b2987b333","type":"SEND"}"}
- 意外字符('s'(代码 115)):需要用逗号分隔对象条目
双引号对数据“SenderName”中的第一个字段做了奇怪的事情。
代码:
我们如何使用 jackson 将对象序列化为 JSON 以通过 Redis 发送消息:
(https://user-images.githubusercontent.com/8813159/104827760-06717600-5827-11eb-8cd6-48554db93c49.png)
我们如何尝试使用 jackson 反序列化 JSON 以从我们从 redis 获得的消息中获取对象:
(https://user-images.githubusercontent.com/8813159/104827779-45073080-5827-11eb-84fc-47673c395b69.png)
Redis 元数据class:
(https://user-images.githubusercontent.com/8813159/104827795-5cdeb480-5827-11eb-9595-c9326ca59e3f.png)
控制台日志:
(https://user-images.githubusercontent.com/8813159/104827799-66681c80-5827-11eb-8801-4c107df0dcb6.png)
(https://user-images.githubusercontent.com/8813159/104827801-6d8f2a80-5827-11eb-9170-80635c74110f.png)
我们非常感谢您的帮助,因为我们已经尝试了一切但没有运气,
提前致谢!
问题就在那里
如您所见,数据和元数据值被转换为字符串,然后设置到主 ObjectNode 中。
问题在于,当反序列化时,它被转换为字符串值(我不知道它实际上是如何调用的)实际上不是值的树形式,并且不能用 ObjectMapper#treeToValue
。解决方案是将值转换为 ObjectMapper#valueToTree
的 ObjectNode 并设置为 ObjectNode#set(String, JsonNode)
.
另一种解决方案是更改反序列化部分,而不是尝试直接使用 ObjectMapper#treeToValue
将其转换为 ObjectMapper#readValue
.
我的开发团队在使用 jackson 时遇到了一些问题。
一些不重要的上下文 我们对 jackson 还很陌生,过去我们遇到过几个问题,但我们一直试图用我们从互联网上得到的东西来解决它们,并用过去的问题在 Whosebug 上解决。
有用信息 我们正在将 Java 实例化对象解析为 JSON,这样我们就可以将它们作为字符串通过 redis 发送,然后通过 pub/sub 系统将它们再次作为原始类型的对象再次获取结束。
我们有 2 个字段,每个字段代表不同的对象:
Data: a ChannelMessage object.
String senderName, message;
Enum:ServerType serverType;
Metadata: a RedisMetadata object.
String id, channelName, serverId;
Enum:MessageType type;
所以我们的 JSON 应该看起来像这样:
{
"data": {
"senderName": "PixelDev1729",
"message": "asd",
"serverType": "HUB"
},
"metadata": {
"id": "1bba40f5-74ed-4ab8-ad81-83078ac11421",
"channelName": "global-chat",
"serverId": "b4409522-6a97-47f5-ad75-661ed86c52e8",
"type": "SEND"
}
}
几个头疼 我们已经尝试使用 ObjectNodes 从对象中将值写入字符串。
我们得到了一个非常混乱的 JSON 字符串,其中有很多转义符(反斜杠)。
{"data":"{\"senderName\":\"PixelDev1729\",\"message\":\"asd\",\"serverType\":\"HUB\"}","metadata":"{\"id\":\"e0f77d09-cafa-4ff5-b553-0f0dc4bb76e3\",\"cha|
nnelName":"global-chat","serverId":"9f10cf0b-d3eb-4804-98aa-92d747d75f5e","type":"SEND"}"}
- “没有字符串参数 constructor/factory 方法从字符串值反序列化(列:1,行:1)。”根据我的专业知识,我可以说 Jackson 得到的 JSON 字符串无效。
如此不同的方法...
将 jsonString.replaceAll("^\"|\"$|\\", "");
用于我们首先得到的相同字符串。
结果几乎有效 JSON 但仍然无效,因为我们缺少一些双引号。
{"data":"{"senderName":"wasmake","message":"sadasdas","serverType":"VALHEIM"}","元数据":"{"id":"410c429c-06a4-466a-bce2-5edd63fabe17",| "channelName":"global-chat","serverId":"640d01c3-5b13-4dcf-84bc-1d6b2987b333","type":"SEND"}"}
- 意外字符('s'(代码 115)):需要用逗号分隔对象条目
双引号对数据“SenderName”中的第一个字段做了奇怪的事情。
代码:
我们如何使用 jackson 将对象序列化为 JSON 以通过 Redis 发送消息: (https://user-images.githubusercontent.com/8813159/104827760-06717600-5827-11eb-8cd6-48554db93c49.png)
我们如何尝试使用 jackson 反序列化 JSON 以从我们从 redis 获得的消息中获取对象: (https://user-images.githubusercontent.com/8813159/104827779-45073080-5827-11eb-84fc-47673c395b69.png)
Redis 元数据class: (https://user-images.githubusercontent.com/8813159/104827795-5cdeb480-5827-11eb-9595-c9326ca59e3f.png)
控制台日志:
(https://user-images.githubusercontent.com/8813159/104827799-66681c80-5827-11eb-8801-4c107df0dcb6.png)
(https://user-images.githubusercontent.com/8813159/104827801-6d8f2a80-5827-11eb-9170-80635c74110f.png)
我们非常感谢您的帮助,因为我们已经尝试了一切但没有运气, 提前致谢!
问题就在那里
如您所见,数据和元数据值被转换为字符串,然后设置到主 ObjectNode 中。
问题在于,当反序列化时,它被转换为字符串值(我不知道它实际上是如何调用的)实际上不是值的树形式,并且不能用 ObjectMapper#treeToValue
。解决方案是将值转换为 ObjectMapper#valueToTree
的 ObjectNode 并设置为 ObjectNode#set(String, JsonNode)
.
另一种解决方案是更改反序列化部分,而不是尝试直接使用 ObjectMapper#treeToValue
将其转换为 ObjectMapper#readValue
.