6

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?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
GC_
  • 1,673
  • 6
  • 23
  • 39

2 Answers2

5

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
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • what would be the exact exception class? (I'm lazy to open some log files to see :) ) – Bozho Sep 09 '10 at 18:09
  • @Bozho: I added some more detail during a quick edit. It's servletcontainer specific. – BalusC Sep 09 '10 at 18:11
  • So your saying that write throws an exception, when it blocks, due to a user's cancel. – GC_ Sep 09 '10 at 18:16
  • Sounds like you're using multiple threads to write the data. Blocking like that is by the way not normal. – BalusC Sep 09 '10 at 18:29
  • No, not really. Just one thread. However, without the catch you mentioned the write blocks. – GC_ Sep 09 '10 at 18:41
2

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
  • 265,237
  • 58
  • 395
  • 493
  • 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. – GC_ Sep 09 '10 at 18:17