如何将OutputStream管道传输到StreamingDataHandler? [英] How can you pipe an OutputStream to a StreamingDataHandler?

查看:89
本文介绍了如何将OutputStream管道传输到StreamingDataHandler?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在JAX-WS中有一个Java Web服务,该服务从另一个方法返回OutputStream.除了创建临时文件,对其进行写入,然后再次将其作为InputStream备份打开之外,我似乎无法弄清楚如何将OutputStream流传输到返回的DataHandler中.这是一个示例:

I've got a Java web service in JAX-WS that returns an OutputStream from another method. I can't seem to figure out how to stream the OutputStream into the returned DataHandler any other way than to create a temporary file, write to it, then open it back up again as an InputStream. Here's an example:

@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来传输数据的原因.我似乎无法全神贯注于如何直接从需要提供给返回的DataHandler的OutputStream流数据(最终是接收StreamingDataHandler的客户端).

The main issue is that the writeToOut() method can return data that are far larger than the computer's memory. That's why the method is using MTOM in the first place - to stream the data. I can't seem to wrap my head around how to stream the data directly from the OutputStream that I need to provide to the returned DataHandler (and ultimately the client, who receives the StreamingDataHandler).

我已经尝试过使用PipedInputStream和PipedOutputStream,但这些似乎并不是我真正需要的,因为在将PipedOutputStream写入之后,需要返回DataHandler.

I've tried playing around with PipedInputStream and PipedOutputStream, but those don't seem to be quite what I need, because the DataHandler would need to be returned after the PipedOutputStream is written to.

有什么想法吗?

推荐答案

我按照Christian所说的思路(创建一个新线程执行writeToOut())找出了答案:

I figured out the answer, along the lines that Christian was talking about (creating a new thread to execute 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()时会阻塞;同时,输入流返回给客户端,客户端通过读取数据来取消对写入的阻止. (我以前对该解决方案的实现存在的问题是我没有正确关闭流,从而遇到错误.)

It is a tad more complex due to final variables, but as far as I can tell this is correct. When the thread is started, it blocks when it first tries to call out.write(); at the same time, the input stream is returned to the client, who unblocks the write by reading the data. (The problem with my previous implementations of this solution was that I wasn't properly closing the stream, and thus running into errors.)

这篇关于如何将OutputStream管道传输到StreamingDataHandler?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆