Hi,
I am using the Stream API to upload files from the browser (using
XMLHttpRequest send method) to a server and then, from that server to an
external system that is the one who finally creates the file.
The code on the controller (using Spring MVC) is something like this:
//...
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iter = upload.getItemIterator(request);
InputStream fileStream = null;
try {
while (iter.hasNext) {
FileItemStream item = iter.next();
//...
if (item.getFieldName().equals("file")) {
fileStream = item.openStream();
// process stream
}
} catch (Exception e) {
//...
} finally {
if (fileStream != null) {
fileStream.close(); // this can take a long time if an exception happens
processing the stream
}
}
The problem is that closing the stream can take a long time if an exception
happens ( for instance, the external system is unavailable).
Looking the ItemInputStream source code it seems that the close method read the
file before closing it. Actually, my front end think the server is reading the
file.
public void close(boolean pCloseUnderlying) throws IOException {
if (closed) {
return;
}
if (pCloseUnderlying) {
closed = true;
input.close();
} else {
for (;;) {
int av = available();
if (av == 0) {
av = makeAvailable();
if (av == 0) {
break;
}
}
skip(av);
}
}
closed = true;
}
I have also tried using the hard close options:
if (fileStream instanceof ItemInputStream) {
// if aborted, do a hard close, otherwise the default close would read
the whole file
((MultipartStream.ItemInputStream)fileStream).close(aborted);
} else {
fileStream.close();
}
}
This works fine in Chrome but in Safari the request hangs indefinitely.
Is there any reliable way of closing the stream without reading the file or is
this the expected behaviour?
Thanks,
Iván.