Java Restlet-使用StreamingOutput的StreamClosedException

Java Restlet-使用StreamingOutput的StreamClosedException,java,exception,restlet,truezip,Java,Exception,Restlet,Truezip,我的Restlet资源遇到问题。它使用TrueZip构建Zip存档的子集,并允许用户下载它 // Create a Streaming Response Entity. final StreamingOutput stream = new StreamingOutput() { @Override public void write(final OutputStream output) { ZipBrowser.extrac

我的Restlet资源遇到问题。它使用TrueZip构建Zip存档的子集,并允许用户下载它

// Create a Streaming Response Entity.
    final StreamingOutput stream = new StreamingOutput() {
        @Override
        public void write(final OutputStream output) {
                ZipBrowser.extract(source, path, output);
        }
    };
    LOGGER.debug("Download of Path {} with the length {} initiated", path, length);
    ResponseBuilder rb = Response.ok(stream);
    rb.header(HeaderConstants.HEADER_CONTENT_DISPOSITION, CONDISPOVALUE + fileName);
    rb.header(HeaderConstants.HEADER_CONTENT_LENGTH, length);
    return rb.build();
即使它工作,我收到一个恼人的感觉。仅当我尝试下载一个子集而不是整个Zip存档时,才会出现此错误:

An exception occured writing the responseentity

    sun.net.httpserver.StreamClosedException
    at sun.net.httpserver.ChunkedOutputStream.flush(ChunkedOutputStream.java:156)
    at sun.net.httpserver.PlaceholderOutputStream.flush(ExchangeImpl.java:449)
    at org.restlet.engine.adapter.ServerCall.writeResponseBody(ServerCall.java:511)
    at org.restlet.engine.adapter.ServerCall.sendResponse(ServerCall.java:454)
    at org.restlet.engine.adapter.ServerAdapter.commit(ServerAdapter.java:187)
    at org.restlet.engine.adapter.HttpServerHelper.handle(HttpServerHelper.java:144)
    at org.restlet.engine.connector.HttpServerHelper$1.handle(HttpServerHelper.java:64)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77)
    at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:80)
    at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:677)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77)
    at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:649)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)Unable to send error response

    java.io.IOException: headers already sent

    at sun.net.httpserver.ExchangeImpl.sendResponseHeaders(ExchangeImpl.java:204)
    at sun.net.httpserver.HttpExchangeImpl.sendResponseHeaders(HttpExchangeImpl.java:86)
    at org.restlet.engine.connector.HttpExchangeCall.writeResponseHead(HttpExchangeCall.java:148)
    at org.restlet.engine.adapter.ServerCall.sendResponse(ServerCall.java:450)
    at org.restlet.engine.adapter.ServerAdapter.commit(ServerAdapter.java:205)
    at org.restlet.engine.adapter.HttpServerHelper.handle(HttpServerHelper.java:144)
    at org.restlet.engine.connector.HttpServerHelper$1.handle(HttpServerHelper.java:64)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77)
    at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:80)
    at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:677)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77)
    at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:649)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

这是由于zip库和Restlet框架都试图在完成后关闭
OutputStream

我以前在其他库中也遇到过这种情况,并且通过将传递给zip库的
OutputStream
封装在一个类中,该类重写
close()
而不执行任何操作,成功地消除了异常。委托其他所有方法。然后,这允许Restlet关闭流

因此,在代码中调用Zip实用程序的行变成:

 ZipBrowser.extract(source, path, new WrappedOutputStream(output));
其中
wrappedOutStream
类如下所示(需要添加委派方法)


好主意!刚刚试过,效果不错。非常感谢:-)
import java.io.IOException;
import java.io.OutputStream;

public class WrappedOutputStream extends OutputStream {

    private final OutputStream delegate;

    public WrappedOutputStream(final OutputStream delegate) {
        this.delegate = delegate;
    }

    public void close() throws IOException {
        // Do Nothing to allow Restlet to close the underlying stream
    }

    // TODO Delegate other Outpt Stream methods.
}