1

我有一个基于 Axis2 1.4.1 的 SOAP Web 服务,它使用文档中的模式接受 MTOM 上传:

public class MTOMService {
    public void uploadFileUsingMTOM(OMElement element) throws Exception {
        OMText binaryNode = (OMText) (element.getFirstElement()).getFirstOMChild();
        DataHandler actualDH;
        actualDH = (DataHandler) binaryNode.getDataHandler();

        // consume data from DataHandler
        InputStream inputStream = actualDH.getInputStream();
    }
}

我可能需要多次从 DataHandler 读取数据。

        inputStream.close();
        // get second InputStream to consume same data from DataHandler again
        InputStream inputStream2 = actualDH.getInputStream();

这适用于简单的测试。我可以假设这总是安全的吗?

  • 我在文档中找不到任何明确的东西,无论是标准 DataHandler 还是 Axiom 实现的特定 DataSource(但我可能错过了)
  • Axis 1.4.1 使用 Axiom 1.2.9,它将附件表示为
    • PartOnFile,从支持重用的内存假脱机到磁盘,直到(我认为)SOAP请求结束;通过阅读FileAccessor
    • PartOnMemoryEnhanced,它将数据存储在多个byte数组中,因此应该支持重用,直到垃圾收集
  • 展望未来,更高版本的 Axiom 使用不同的类ParserInputStreamDataSource,它支持不同的破坏性或非破坏性Behavior枚举,但 Axis 主干没有指定,因此 Axiom 默认Behavior.NON_DESTRUCTIVE允许重新读取。

但这都是对代码的粗略扫描,我不是很了解,所以我可能错过了其他代码路径,或者我可能错了。

Axis 或此处的任何其他接口是否保证可以多次读取 DataHandlers?如果没有,是否有一个很好的机制来检测 Axis 何时传递附件只读模式,以便我可以自己缓存第一次读取?请求是否为 MTOM 是否有区别?谢谢!

4

1 回答 1

1

DataHandler#getInputStream()方法基本上委托给该方法,并且该方法的合同特别要求可以多次读取DataSource#getInputStream()该内容。DataSourceAxiom 旨在符合该合同。

Axiom 定义了一个扩展接口 ( DataHandlerExt),可以在想要“破坏性地”读取内容的场景中使用。

然而,您需要注意一件事:在请求处理结束时(即在您的服务被调用之后),Axis2 应指示 Axiom 销毁与DataHandler请求期间创建的实例相关的临时文件。这意味着如果您存储对 a 的引用DataHandler并稍后尝试访问它(在另一个请求中或在某个后台线程中),那么这可能会失败。请注意,在 Axiom 的未来版本中,计划引入一个选项,让垃圾收集器处理该清理,从而避免此问题。

于 2013-08-06T20:17:20.403 回答