首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将固定大小映射序列化为CBOR

将固定大小映射序列化为CBOR
EN

Stack Overflow用户
提问于 2018-02-26 15:19:51
回答 2查看 1.5K关注 0票数 5

我有以下JSON:

代码语言:javascript
复制
[
  {
    2: {
      "c": true
    }
  },
  {
    3: {
      "p": 10
    }
  }
]

我想转换成CBOR格式。因此,对于cbor.me,我有以下输出:

82A102A16163F5A103A161700A

但是,当使用Jackson二进制CBOR序列化程序时,我有以下输出:

82BF02BF6163F5FFF03BF61700AFFFF

这没有错,但没有优化.我有一个额外的4个不必要的字节,它可以是什么。

然后,我尝试手动序列化JSON,但结果相同:

代码语言:javascript
复制
@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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-10 12:46:00

通过使用版本2.9.4,在CBORGenerator类中可以使用以下方法:public final void writeStartObject(int elementsToWrite)

代码语言:javascript
复制
@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

票数 0
EN

Stack Overflow用户

发布于 2019-10-28 19:50:32

在使用更新或更好的编码器时,您已经收到了答案。但对于其他晚来这里的人来说..。

问题是OP的编码器使用了不确定长度的映射,然后“断开”原语来跳出并转到下一项。

将该版本与断续原语进行比较:

代码语言:javascript
复制
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(*)

对于没有它们的版本:

代码语言:javascript
复制
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将是有问题的,如果这是您所关心的事情。

这是一个错误的编码器的问题,不应该使用无限长的映射/中断。有时间使用这些,但只在“流”模式,这是不可能给出的例子。如果您有所有的项目预先和编码,使用不确定是不需要的。如果您有一定数量的映射,但不确定有多少映射,并且希望开始编码所拥有的内容,那么就需要不确定长度的映射或字符串。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48991682

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档