我有以下JSON:
[
{
2: {
"c": true
}
},
{
3: {
"p": 10
}
}
]我想转换成CBOR格式。因此,对于cbor.me,我有以下输出:
82A102A16163F5A103A161700A
但是,当使用Jackson二进制CBOR序列化程序时,我有以下输出:
82BF02BF6163F5FFF03BF61700AFFFF
这没有错,但没有优化.我有一个额外的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();
}这是杰克逊二进制格式库中的一个bug,还是ObjectMapper中缺少了一些配置属性?
编辑:这似乎是一个已知的问题:https://github.com/FasterXML/jackson-dataformats-binary/issues/3
发布于 2018-03-10 12:46:00
通过使用版本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
发布于 2019-10-28 19:50:32
在使用更新或更好的编码器时,您已经收到了答案。但对于其他晚来这里的人来说..。
问题是OP的编码器使用了不确定长度的映射,然后“断开”原语来跳出并转到下一项。
将该版本与断续原语进行比较:
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实际上意味着“真”。从0xF5 (11110101)取前三位(CBOR主要类型),您将得到小数点21,即已建立的CBOR "true“(0x00010101)。
此外,将值2赋值为映射的名称(其中包含"c"="true“)是完全有效的。但是要注意,当使用值作为名称时,转换为JSON将是有问题的,如果这是您所关心的事情。
这是一个错误的编码器的问题,不应该使用无限长的映射/中断。有时间使用这些,但只在“流”模式,这是不可能给出的例子。如果您有所有的项目预先和编码,使用不确定是不需要的。如果您有一定数量的映射,但不确定有多少映射,并且希望开始编码所拥有的内容,那么就需要不确定长度的映射或字符串。
https://stackoverflow.com/questions/48991682
复制相似问题