我有一个基于 Axis2 1.4.1 的 SOAP Web 服务,它使用 pattern from the docs 接受 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
,它将数据存储在多个字节
数组中,因此应该支持重复使用,直到垃圾收集
-
- 展望 future ,Axiom 的更高版本使用不同的类
ParserInputStreamDataSource
它支持不同的破坏性或非破坏性Behavior
枚举,但 Axis trunk 未指定,因此 Axiom 默认为允许重新读取的Behavior.NON_DESTRUCTIVE
。
但这都是对代码的粗略扫描,我不太了解,所以我可能错过了其他代码路径,或者我可能只是错了。
Axis 或此处的任何其他接口(interface)是否保证 DataHandler 可以被多次读取?如果没有,是否有一个好的机制来检测 Axis 何时传递附件只读模式,以便我可以自己缓存第一次读取?请求是否为 MTOM 有什么区别吗?谢谢!
最佳答案
DataHandler#getInputStream()
方法基本上委托(delegate)给 DataSource#getInputStream()
,并且该方法的约定特别要求可以多次读取 DataSource
的内容。 Axiom 的设计就是为了遵守该契约(Contract)。
Axiom 定义了一个扩展接口(interface) (DataHandlerExt
),可用于想要“破坏性”读取内容的场景。
但是,您需要注意一件事:在请求处理结束时(即调用您的服务后),Axis2 应指示 Axiom 销毁与请求期间创建的 DataHandler
实例相关的临时文件。这意味着,如果您存储对 DataHandler 的引用并尝试稍后访问它(在另一个请求中或在某个后台线程中),则这可能会失败。请注意,在 Axiom 的 future 版本中,计划引入一个选项,让垃圾收集器处理该清理工作,从而避免此问题。
关于java - 从 Apache Axis2、MTOM 中的 DataHandler 重新读取附件是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18064283/