当前推荐的将 byte[] 转换为 JsonNode 并返回的方法

Posted

技术标签:

【中文标题】当前推荐的将 byte[] 转换为 JsonNode 并返回的方法【英文标题】:Current recommended way to convert byte[] to JsonNode and back 【发布时间】:2015-04-01 04:02:06 【问题描述】:

我想从 Java 字节数组中读取 JSON“树”,并使用 Jackson 将 JSON“树”作为 Java 字节数组写回。一种方法如下所示:

ObjectMapper om = new ObjectMapper();
JsonNode old = om.createObjectNode();

byte[] arr = om.writeValueAsBytes(old);
JsonNode new = om.readTree(arr);

然而,Jackson 最近建议使用 ObjectReader 和 ObjectWriter 而不是 ObjectMapper,因为配置中的线程安全,而且还因为可能只与它们相关的优化。但是,ObjectReader 不直接支持带有字节数组的 readTree,并且 writeValueAsBytes 比 writeTree 更通用,因此可能有某种方法(和原因)以某种方式跳过类型映射逻辑。

那么,今天,对于最近的 Jackson (2.5),进行这两次转换的最快/最佳/推荐方式是什么?

【问题讨论】:

【参考方案1】:

直接使用ObjectMapper 的问题在于,如果您更改映射器的配置,可能会导致问题。但是,如果您不更改底层配置,无论如何您应该是安全的(更多阅读 here)。

但是如果你使用ObjectReaderObjectWriter 你是完全安全的,即使你真的改变了映射器的配置。这是可能的,因为读取器/写入器是不可变的,因此无法更改底层状态。

因此,要读取/写入字节,以下方法可以正常工作:

ObjectMapper om = new ObjectMapper();
JsonNode oldNode = om.createObjectNode();

// Writing...
// Create an immutable writer (in this case using the default settings)
final ObjectWriter writer = om.writer();

// Use the writer for thread safe access.
final byte[] bytes = writer.writeValueAsBytes(oldNode);


// Reading...
// Create an immutable reader
final ObjectReader reader = om.reader();

// Use the reader for thread safe access
final JsonNode newNode = reader.readTree(new ByteArrayInputStream(bytes));

所以,基本上你可以使用相同的原则(使用字节流),但如果你需要确保你使用线程安全访问映射器,你应该通过ObjectReader 和@987654330 访问读/写@。

writeValueAsBytes 是这样描述的 in the JavaDoc:

功能上相当于用java.io.ByteArrayOutputStream调用writeValue(Writer,Object)获取字节,但效率更高。

对于阅读,您可以简单地使用readTree(InputStream) 版本。

【讨论】:

你能证明使用 ByteArrayInputStream 与使用 byte[] 的 readTree 一样有效吗?对于他们来说,JsonFactory.createParser(byte[]) 必须与 JsonFactory.createParser(InputStream) 一样高效,我怀疑它是 - 但我可能错了。 @Nakedible,我可以很容易地说我永远不会在这样的事情上作证;)但是,我做了一些简单的performance benchmarks,我比较了不同的方法,输出可以是found here。 好吧,你说服了我,尽管微基准总是撒谎;)谢谢你,很好的回答!

以上是关于当前推荐的将 byte[] 转换为 JsonNode 并返回的方法的主要内容,如果未能解决你的问题,请参考以下文章

如何快速的将图片里的内容转换成文字

如何优雅的将数据从sqlite3迁移到mysql

java.lang.ClassCastException:在尝试通过Instagram共享打印屏幕时,无法将byte []强制转换为android.os.Parcelable错误

编程:将一个数字字符串转换成一个整数(不得调用C语言提供的将字符串转换为整数的函数)。

将列数据转换为xml格式;查询失败,因为当前不支持所有列类型

使用Dozer优雅的将DO转换成VO