2016-02-12 85 views
3

我遇到了Restlet资源的问题。它使用TrueZip构建Zip Archive的一个子集并允许用户下载它。Restlet - 使用StreamingOutput的StreamClosedException

// 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(); 

即使它工作,我收到恼人的StreamClosedException。只有当我尝试下载一个子集,而不是整个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) 

回答

2

这是由拉链库和Restlet框架试图关闭OutputStream一旦他们完成了既造成。

我已经在过去与其他库经历过这种情况,并设法消除异常,通过将OutputStream传递给一个类中的zip库,该类替代close()什么也不做。与所有其他方法委托。这然后允许Restlet关闭流。

这样调用代码中的Zip实用程序的行变成了:

ZipBrowser.extract(source, path, new WrappedOutputStream(output)); 

WrappedOutputStream类如下所示(将需要添加委托方法)。

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. 
} 
+1

好主意!只是试了一下,并工作。非常感谢 :-) – user1291536