我有以下JSON:
[
{
2: {
"c": true
}
},
{
3: {
"p": 10
}
}
]
我想转换为CBOR格式。 根据cbor.me,我有以下输出:
82A102A16163F5A103A161700A
但是,当使用Jackson Binary CBOR Serializer时,我有以下输出:
82BF02BF6163F5FFFFBF03BF61700AFFFF
哪个没有错,但没有优化...我还有4个不必要的字节添加到它真正的内容。
然后我尝试手动序列化JSON但结果相同:
@Override
public void serialize(Request value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
jgen.writeStartArray(value.getDataList().size());
for (Data data : value.getDataList()) {
jgen.writeStartObject(new Map[1]);
jgen.writeFieldId(data.getItem());
jgen.writeStartObject();
if (data.getObject().getC() != null) {
jgen.writeBooleanField("c", data.getObject().getC());
}
if (data.getObject().getP() != null) {
jgen.writeNumberField("p", data.getObject().getP());
}
jgen.writeEndObject();
jgen.writeEndObject();
}
jgen.writeEndArray();
}
这是Jackson二进制格式库的错误还是我错过了ObjectMapper的一些配置属性?
编辑:这似乎是一个众所周知的问题:https://github.com/FasterXML/jackson-dataformats-binary/issues/3
答案 0 :(得分:1)
您已经收到使用更新或更好的编码器的答案。但是对于以后再来的其他人...
问题是OP的编码器使用了不确定的长度映射,然后使用“ BREAK”原语进行分解并转到下一个项目。
将版本与中断原语进行比较:
82 # array(2)
BF # map(*)
02 # unsigned(2)
BF # map(*)
61 # text(1)
63 # "c"
F5 # primitive(21)
FF # primitive(*)
FF # primitive(*)
BF # map(*)
03 # unsigned(3)
BF # map(*)
61 # text(1)
70 # "p"
0A # unsigned(10)
FF # primitive(*)
FF # primitive(*)
对于没有它们的版本:
82 # array(2)
A1 # map(1)
02 # unsigned(2)
A1 # map(1)
61 # text(1)
63 # "c"
F5 # primitive(21)
A1 # map(1)
03 # unsigned(3)
A1 # map(1)
61 # text(1)
70 # "p"
0A # unsigned(10)
您看到地图(*)与地图(1)吗?
通过使用具有特定长度而不是不确定长度的映射,所得的CBOR可以使用“一个映射即将到来,它就在这里”而不是“ IDK!映射即将来临!这是一个!现在停止!”
在第二个示例中,仍然有一个原语,但这不是BREAK命令。 0xF5有效表示“ true”。取0xF5(11110101)的前三位(CBOR主要类型),然后将十进制21设置为已建立的CBOR“ true”(0x00010101)。
此外,将值2分配为在其中包含“ c” =“ true”的地图名称是完全有效的。但是请注意,如果您担心的话,在将值用作名称时转换为JSON将是有问题的。
这是编码器质量较差的问题,不应该使用不确定的长度映射/中断。有时间使用它们,但是只能在“流”模式下使用,对于给定的示例来说是不可能的。如果您将所有项目放在前面并进行编码,则不需要使用不定式。如果您有一定数量的地图,但不确定要映射多少,并希望开始对自己所拥有的内容进行编码,那就是需要无限长的地图或字符串的方法。
答案 1 :(得分:0)
通过使用版本2.9.4
,CBORGenerator
课程中提供了以下方法:public final void writeStartObject(int elementsToWrite)
@Override
public void serialize(Request value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
jgen.writeStartArray(value.getDataList().size());
for (Data data : value.getDataList()) {
((CBORGenerator) jgen).writeStartObject(1);
jgen.writeFieldId(data.getItem());
((CBORGenerator) jgen).writeStartObject(1);
if (data.getObject().getC() != null) {
jgen.writeBooleanField("c", data.getObject().getC());
}
if (data.getObject().getP() != null) {
jgen.writeNumberField("p", data.getObject().getP());
}
jgen.writeEndObject();
jgen.writeEndObject();
}
jgen.writeEndArray();
}
我有以下输出:
82A102A16163F5A103A161700A