I\'m using Jersey 2.13 in my web application for retrieving data async. There are some cases where requests take some time (i.E. when executing complex reports) until their
I worked around this issue by adding a low priority WriterInterceptor
that detects and ignores exceptions thrown while writing responses. If you're running on Tomcat and don't mind a dependency on Tomcat classes, you could use org.apache.catalina.connector.ClientAbortException
rather calling setOutputStream
, which would remove the need for the two nested classes (and the dependency on org.apache.commons.io.output.ProxyOutputStream
, which could easily also be avoided with a custom OutputStream
subclass instead).
import java.io.IOException;
import java.io.OutputStream;
import javax.annotation.Priority;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;
import org.apache.commons.io.output.ProxyOutputStream;
/**
* Ignore exceptions when writing a response, which almost always means the
* client disconnected before reading the full response.
*/
@Provider
@Priority(1)
public class ClientAbortExceptionWriterInterceptor implements WriterInterceptor {
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException {
context.setOutputStream(new ClientAbortExceptionOutputStream(context.getOutputStream()));
try {
context.proceed();
} catch (Throwable t) {
for (Throwable cause = t; cause != null; cause = cause.getCause()) {
if (cause instanceof ClientAbortException) {
return;
}
}
throw t;
}
}
private static class ClientAbortExceptionOutputStream extends ProxyOutputStream {
public ClientAbortExceptionOutputStream(OutputStream out) {
super(out);
}
@Override
protected void handleIOException(IOException e) throws IOException {
throw new ClientAbortException(e);
}
}
@SuppressWarnings("serial")
private static class ClientAbortException extends IOException {
public ClientAbortException(IOException e) {
super(e);
}
}
}