Asynchronous 使用Jersey MultiPart file upload时InputStream意外关闭&;服务器发送事件(SSE)

Asynchronous 使用Jersey MultiPart file upload时InputStream意外关闭&;服务器发送事件(SSE),asynchronous,file-upload,jersey,multipart,server-sent-events,Asynchronous,File Upload,Jersey,Multipart,Server Sent Events,我使用Jersey Multipart通过Rest API将文件上传到服务器。在resource方法中,我通过InputStream访问文件内容。我想返回上传的文件大小到客户端使用,以便客户端可以轻松地获得上传的文件大小直接从上传资源的方法。 我正在使用Jersey作为java和Grizzly Http服务器中的JAX-RS实现。这是我的密码: @POST @Path("upload") @Produces(SseFeature.SERVER_SENT_EVENTS) @Consumes("mu

我使用Jersey Multipart通过Rest API将文件上传到服务器。在resource方法中,我通过InputStream访问文件内容。我想返回上传的文件大小到客户端使用,以便客户端可以轻松地获得上传的文件大小直接从上传资源的方法。 我正在使用Jersey作为java和Grizzly Http服务器中的JAX-RS实现。这是我的密码:

@POST
@Path("upload")
@Produces(SseFeature.SERVER_SENT_EVENTS)
@Consumes("multipart/form-data;charset=utf-8")
public EventOutput upload(@FormDataParam("file") InputStream file,
                          @FormDataParam("file") FormDataContentDisposition fileDisposition) {
    final EventOutput eventOutput = new EventOutput();
    try {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    int read = -1;
                    byte[] buffer = new byte[1024];
                    OutboundEvent.Builder eventBuilder
                            = new OutboundEvent.Builder();
                    OutboundEvent event = null;
                    long totalRead = 0, lastReadMB = 0;

                    while ((read = file.read(buffer)) != -1) {
                        totalRead += read;
                        if (lastReadMB != (totalRead / (1024 * 1024))) {
                            lastReadMB = totalRead / (1024 * 1024);
                            event = eventBuilder.name("uploaded").data(Long.class, totalRead).build();
                            eventOutput.write(event);
                        }
                    }
                    event = eventBuilder.name("uploaded").data(Long.class, totalRead).build();
                    eventOutput.write(event);
                } catch (Exception e) {
                    throw new RuntimeException(
                            "Error when writing the event.", e);
                } finally {
                    try {
                        eventOutput.close();
                    } catch (Exception ioClose) {
                        throw new RuntimeException(
                                "Error when closing the event output.", ioClose);
                    }
                }
            }
        }).start();
        return eventOutput;
    } catch (Exception e) {
        logger.error(e.toString(), e);
    }
    throw new WebApplicationException(Response.status(Response.Status.INTERNAL_SERVER_ERROR).
            entity("something happened").build());
}
​ 问题是,当我的资源方法将EventOutput作为响应和请求处理线程返回到I/O容器时,InputStream关闭,处理线程无法访问上载的文件。例外情况如下:

Exception in thread "Thread-1" java.lang.RuntimeException: Error when writing the event.
    at com.WebService.ContentService$1.run(ContentService.java:192)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.jvnet.mimepull.MIMEParsingException: java.io.IOException: Stream Closed
    at org.jvnet.mimepull.WeakDataFile.read(WeakDataFile.java:115)
    at org.jvnet.mimepull.DataFile.read(DataFile.java:77)
    at org.jvnet.mimepull.FileData.read(FileData.java:69)
    at org.jvnet.mimepull.DataHead$ReadMultiStream.fetch(DataHead.java:265)
    at org.jvnet.mimepull.DataHead$ReadMultiStream.read(DataHead.java:219)
    at java.io.InputStream.read(InputStream.java:101)
    at com.WebService.ContentService$1.run(ContentService.java:181)
    ... 1 more
Caused by: java.io.IOException: Stream Closed
    at java.io.RandomAccessFile.seek0(Native Method)
    at java.io.RandomAccessFile.seek(RandomAccessFile.java:557)
    at org.jvnet.mimepull.WeakDataFile.read(WeakDataFile.java:112)
    ... 7 more

​ 1-代码中有什么问题?为什么在文件传输的中间关闭输入流?< BR/> BR/>
2-是否有其他方法将上传的文件大小返回到服务器端的客户端?(要求:上传资源方法必须在不同线程中异步处理上传文件)

我认为不需要SSE。只要在@peeskillet中运行,我想通知客户机有多少内容是通过与客户机用于上载文件相同的HTTP连接上载到服务器的。在异步模式下,上载完成后将通知客户端。@peeskillet我希望客户端能够显示上载进度条,其中包含从上载资源方法接收的SSE事件(上载事件)。