关于持久性和XML使用InputStream的最佳方法

时间:2009-03-12 12:04:05

标签: java xml web-services inputstream

我有一个REST Web服务,它监听POST请求并从客户端抓取XML有效负载并将其最初存储为InputStream,即在Representation对象上,您可以调用getStream()。 / p>

我想利用InputStream中保存的XML,我开始认为坚持它是明智的,所以我可以多次查询数据 - 一旦你读完它,对象就变成了空。所以我考虑将InputStream转换为字符串。这不是一个好主意,因为来自javax.xml.parsers库的DocumentBuilder.parse()只允许您传递:

  • InputStreams
  • 文件
  • 网址
  • SAX InputSources

不是字符串。

对于解析XML的问题,我应该在这里使用InputStreams做什么? 请记住,我希望通过代码在将来的流程中重新询问XML。

6 个答案:

答案 0 :(得分:2)

如果您有一个InputStream,并希望将其用作XML文档,那么为什么不简单地解析它并传递Document对象?如果要保留此对象,请使用序列化程序将其作为文本写回。

正如我在Tom Hawtin的评论中所指出的,编码在处理XML时非常重要。不是在这里写一篇可能会错过你特定情况的长篇文章,而是我写的article

编辑:实际上,由于我的文章没有具体谈论网络服务,我应该在这里深入探讨一下。有两个地方可以指定内容编码:在XML序言中,或在 Content-Type 响应头中。根据XML规范,前者是您想要使用的,并且它是解析器将使用的。在大多数情况下,这并不重要:由不了解规范的人设置的Web服务通常会使用没有字符集规范的text / xml(这是不正确的,但可能不会造成伤害)。如果他们正确地做了事情,他们将使用utf-8编码指定application / xml。但是,你应该验证你得到了什么,这样你就不会得到一些解析器无法处理的奇怪编码。

答案 1 :(得分:1)

通常,当我们谈论持久性时,我们谈论的是将其写入磁盘或其他媒体。那里有性能影响,你必须考虑磁盘空间问题。你需要权衡这与长期使用XML的价值。

如果你只是在谈论将它保存在内存中(这听起来像你要问的那样),那么你可以分配一个字节数组,并将整个内容读入字节数组。您可以使用ByteArrayInputStream来读取和重新读取该流。

这个成本是双倍的。首先,您在内存中保留了一份副本,并且需要根据可扩展性要求进行权衡。其次,解析XML有点贵,所以如果可能的话,最好只解析一次,并将结果保存在对象中。

编辑:

要分配和读取字节数组,您通常(但不总是)依赖InputStream的available()方法来告诉您要分配多少。并使用DataInputStream包装InputStream,以便您可以通过一次调用调用readFully()将整个内容吸入字节数组中。

再次编辑:

阅读斯蒂恩的评论如下。他是对的,在这种情况下使用available()是个坏主意。

答案 2 :(得分:1)

我建议使用Apache Commons IO库。 IOUtils类包含许多将InputStreams转换为String的便捷方法,反之亦然。

答案 3 :(得分:0)

我认为你应该研究一些更适合保存编码的结构(即更多编码不可知)。对于低级结构,请考虑byte[](但要注意内存释放!)或者您可以尝试设计适合您需求的数据类型。

您可以将InputStream读入ByteArrayOutputStream(使用其中一种read()方法)并从there中提取byte[]

答案 4 :(得分:0)

如果你想多次使用XML,为什么不从InputStream中解析一次(这是繁重的工作),然后坚持返回Document?

答案 5 :(得分:-2)

java.io.StringReader将允许您使用InputSource

您可能希望将数据存储在byte[]中,然后使用ByteArrayInputStream进行阅读。如果它特别大,您可能想要考虑压缩。这可以通过GzipInputStream读出,BufferedInputStream通常应该包含在{{1}}中。