3

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

我想利用 InputStream 中保存的 XML,我开始认为保留它是明智的,所以我可以多次询问数据 - 因为一旦你通读它,对象就会变为 null。所以我考虑将 InputStream 转换为字符串。这不是一个好主意,因为 javax.xml.parsers 库中的 DocumentBuilder.parse() 只允许您通过:

  • 输入流
  • 文件
  • 网址
  • SAX 输入源

不是字符串。

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

4

6 回答 6

2

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

正如我在对 Tom Hawtin 的评论中所指出的,编码在处理 XML 时非常重要。与其在这里写一篇可能会错过您的具体情况的长篇文章,不如在这里 写一篇我写的文章。

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

于 2009-03-12T12:19:07.617 回答
1

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

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

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

编辑:

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

再次编辑:

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

于 2009-03-12T12:10:29.477 回答
1

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

于 2009-03-12T12:11:29.397 回答
0

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

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

于 2009-03-12T12:09:14.223 回答
0

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

于 2009-03-12T12:17:18.917 回答
-2

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

您可能希望将数据存储在 a 中byte[],然后使用ByteArrayInputStream. 如果它特别大,您可能需要考虑压缩。这可以被读出 iwth GzipInputStream,它通常应该被包裹在一个BufferedInputStream.

于 2009-03-12T12:08:44.973 回答