Asynchronous 使用Jersey MultiPart file upload时InputStream意外关闭&;服务器发送事件(SSE)
我使用Jersey Multipart通过Rest API将文件上传到服务器。在resource方法中,我通过InputStream访问文件内容。我想返回上传的文件大小到客户端使用,以便客户端可以轻松地获得上传的文件大小直接从上传资源的方法。 我正在使用Jersey作为java和Grizzly Http服务器中的JAX-RS实现。这是我的密码: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
@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事件(上载事件)。