2

由于 Mongo 使用 BSON,我使用 Java API 中的 BSONDecoder 从 Mongo 查询中获取 BSON 文档并打印字符串输出。在下面的 byte[] 数组中存储了 MongoDB 文档的字节(当我打印十六进制值时,它们与 Wireshark 中的相同)

  byte[] array = byteBuffer.array();
  BasicBSONDecoder decoder = new BasicBSONDecoder();
  BSONObject bsonObject = decoder.readObject(array);
  System.out.println(bsonObject.toString());

我收到以下错误:

  org.bson.BSONException: should be impossible

原因:java.io.IOException:org.bson 的 org.bson.BasicBSONDecoder$BSONInput.read(BasicBSONDecoder.java:364) 的 org.bson.BasicBSONDecoder$BSONInput._need(BasicBSONDecoder.java:327) 出现意外 EOF。 BasicBSONDecoder.decodeElement(BasicBSONDecoder.java:118) at org.bson.BasicBSONDecoder._decode(BasicBSONDecoder.java:79) at org.bson.BasicBSONDecoder.decode(BasicBSONDecoder.java:57) at org.bson.BasicBSONDecoder.readObject(BasicBSONDecoder .java:42) 在 org.bson.BasicBSONDecoder.readObject(BasicBSONDecoder.java:32) ... 4 更多

查看实现 https://github.com/mongodb/mongo-java-driver/blob/master/src/main/org/bson/LazyBSONDecoder.java看起来它被困在

        throw new BSONException( "should be impossible" , ioe );

以上发生在对数据库的查询中(通过查询,我的意思是 byte[] 数组包含文档长度之后的所有字节)。查询本身包含字符串“ismaster”或十六进制为“x10 ismaster x00 x01 x00 x00 x00 x00”。我怀疑是 {isMaster: 1} 的 BSON 格式,但我还是不明白为什么会失败。

4

2 回答 2

3

你说:

byte[] 数组包含文档长度之后的所有字节

如果您要剥离返回的 BSON 的第一部分,则您没有将有效的 BSON 文档传递给解析器/解码器。

有关详细信息,请参阅BSON 规范,但简而言之,前四个字节是小端格式二进制文档的总大小。

您在代码中遇到了一个异常,该异常基本上是在尝试读取预期的字节数。它将第一个 int32 读取为长度,然后尝试将其其余部分解析为 BSON 元素(并在下一个字节中找不到有效类型时出现异常)。将您从查询中返回的所有内容传递给它,包括文档大小,它将正常工作。

于 2012-08-12T16:33:19.967 回答
2

这工作得很好:

byte[] array = new BigInteger("130000001069734d6173746572000100000000", 16).toByteArray();
BasicBSONDecoder decoder = new BasicBSONDecoder();
BSONObject bsonObject = decoder.readObject(array);
System.out.println(bsonObject.toString());

并产生这个输出:

{“是大师”:1}

byteBuffer 中的字节有问题。请注意,您必须包含整个文档(包括大小的前 4 个字节)。

于 2012-08-12T21:52:02.540 回答