As far as I know neither RESTeasy nor the Servlet API provide a method to check wether a client has closed the connection. But as already answered here and here: The underlying servlet container might throw an IOException
if the response is bigger then the socket buffer.
You can easily test this:
Test Client
@Test
public void testTimeout() throws Exception {
URLConnection connection = new URL("http://yourhost.com/foo").openConnection();
connection.setReadTimeout(1000);
connection.getContent();
}
Resource class
@Path("/foo")
public class SomeResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public Response test() throws InterruptedException {
Thread.sleep(5000l);
String response = RandomStringUtils.random(6000);
return Response.ok(response).build();
}
}
6000 characters is working for me with RESTeasy 3.0.6.Final on Wildlfy 8.1.0.
As this Exception is thrown long after "your" code is executed you can't catch the exception in a resource class or in an exception mapper. The only way is implementing a WriterInterceptor:
@Provider
public class ResponseInterceptor implements WriterInterceptor {
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
try {
context.proceed();
} catch (IOException ex) {
if (ex.getMessage().contains("Broken pipe")) { // ugly but seems like the only chance...
// revert DB changes
}
}
}
}
Here you have no idea which changes in the DB should be reverted. You can inject e.g. the HttpHeaders
or the HttpServletRequest
via @Context
here and maybe set and check a custom header with a transaction id or something like that.