views:

75

answers:

2

How can you tell if the user hit cancel during a download from a Java servlet? What seem to happen for me with IE, the output stream println() blocks. The used hit cancel, but is there a way to time this out or anything like that?

+3  A: 

Wrap OutputStream#write(), #flush() and #close() in a try-catch block on IOException. If caught, then it usually means that the enduser has aborted the request.

To get a step further, you could also catch on a more servletcontainer-specific exception like ClientAbortException on Tomcat and clones (which is a subclass of IOException), but this will make your webapp code unportable to other servletcontainers.


Update: to come back on the blocking issue, you'd like to call flush() after writing a single block of data. This will actually send the data to the client and cause IOException when the underlying socket is closed.

BalusC
what would be the exact exception class? (I'm lazy to open some log files to see :) )
Bozho
@Bozho: I added some more detail during a quick edit. It's servletcontainer specific.
BalusC
So your saying that write throws an exception, when it blocks, due to a user's cancel.
Grae
Sounds like you're using multiple threads to write the data. Blocking like that is by the way not normal.
BalusC
No, not really. Just one thread. However, without the catch you mentioned the write blocks.
Grae
However, catching that exception worked.
Grae
+2  A: 

You won't be able to tell for sure. It depends on how your servlet container is implemented.

When the user hits "Cancel", the browser should close the socket. This will be detectable by the server, of course, but whether the server has the ServletOutputStream "plumbed" directly to the socket's OutputStream is implementation-dependent. If it does, an IOException will be raised the next time the servlet attempts to write data.

If the container buffers output, the servlet might just finish writing data and never know anything went amiss.

erickson
So your saying that if the buffer is large enough, there will be no IOException, because the write will not block. However, I guess the flush would then block.
Grae