我在 JAX-WS 中有一个 Java Web 服务,它从另一个方法返回一个 OutputStream。我似乎无法弄清楚如何将 OutputStream 流式传输到返回的 DataHandler 中,除了创建一个临时文件,写入它,然后再次将其作为 InputStream 打开。这是一个例子:
@MTOM
@WebService
class Example {
@WebMethod
public @XmlMimeType("application/octet-stream") DataHandler service() {
// Create a temporary file to write to
File fTemp = File.createTempFile("my", "tmp");
OutputStream out = new FileOutputStream(fTemp);
// Method takes an output stream and writes to it
writeToOut(out);
out.close();
// Create a data source and data handler based on that temporary file
DataSource ds = new FileDataSource(fTemp);
DataHandler dh = new DataHandler(ds);
return dh;
}
}
主要问题是 writeToOut() 方法可以返回远远大于计算机内存的数据。这就是该方法首先使用 MTOM 来传输数据的原因。我似乎无法理解如何直接从 OutputStream 传输数据,我需要将数据提供给返回的 DataHandler(最终是接收 StreamingDataHandler 的客户端)。
我尝试过使用 PipedInputStream 和 PipedOutputStream,但这些似乎并不是我所需要的,因为在写入 PipedOutputStream 后需要返回 DataHandler。
有任何想法吗?
我按照 Christian 所说的思路找到了答案(创建一个新线程来执行 writeToOut()):
@MTOM
@WebService
class Example {
@WebMethod
public @XmlMimeType("application/octet-stream") DataHandler service() {
// Create piped output stream, wrap it in a final array so that the
// OutputStream doesn't need to be finalized before sending to new Thread.
PipedOutputStream out = new PipedOutputStream();
InputStream in = new PipedInputStream(out);
final Object[] args = { out };
// Create a new thread which writes to out.
new Thread(
new Runnable(){
public void run() {
writeToOut(args);
((OutputStream)args[0]).close();
}
}
).start();
// Return the InputStream to the client.
DataSource ds = new ByteArrayDataSource(in, "application/octet-stream");
DataHandler dh = new DataHandler(ds);
return dh;
}
}
由于它有点复杂final
变量,但据我所知这是正确的。当线程启动时,它在第一次尝试调用时会阻塞out.write()
;同时,输入流返回给客户端,客户端通过读取数据来解除写入阻塞。 (我以前实现此解决方案的问题是我没有正确关闭流,因此遇到了错误。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)