Imagine you have a filter that starts a database transaction, processes the request, and then then attempts to commit the transaction.
doFilter(...) {
...
transaction.begin();
filterChain.doFilter(request, response);
transaction.commit();
}
Using Jersey, there are some problems:
Using ContainerRequestFilter/ContainerResponseFilter.
public ContainerRequest filter(ContainerRequest request) {
...
}
public ContainerResponse filter(ContainerRequest request, ContainerResponse response) {
...
}
This allows exceptions to bubble up to an ExceptionMapper, but splits logic over 2 separate methods/interfaces. The problem is that if there's an exception that doesn't map to a response, the ContainerResponseFilter is never called, so you can't clean up.
What's the preferred way to handle this in a JAX-RS environment? Is there a way to configure the flushing of the response, or is there a class or interface that I'm overlooking?
JAX-RS is an specification (just a definition) and Jersey is a JAX-RS implementation. Jersey framework is more than the JAX-RS Reference Implementation. Jersey provides its own API that extend the JAX-RS toolkit with additional features and utilities to further simplify RESTful service and client development.
A - Servlet Filters are Java classes that can be used to intercept requests from a client before they access a resource at back end. B - Servlet Filters are Java classes that can be used to manipulate responses from server before they are sent back to the client.
A filter is an object that is invoked at the preprocessing and postprocessing of a request. It is mainly used to perform filtering tasks such as conversion, logging, compression, encryption and decryption, input validation etc. The servlet filter is pluggable, i.e. its entry is defined in the web.
I've been researching this a bit as well for a JAX-RS/RESTEasy application. The two options I was considering before reading this question:
ExceptionMapper<Throwable>
(or ExceptionMapper<DaoException>
with a custom DaoException
) and handle it there or in the ContainerResponseFilter
that will get executed because of the ExceptionMapper<?>
handling all exceptions.transaction.begin()
, check the current state of the transaction, and roll back there if needed.There are problems with both options.
ExceptionMapper<Throwable>
too broad, while the ExceptionMapper<DaoException>
might miss some other exception, again leaving the transaction not cleaned up.So after reading your question, I'm currently thinking:
ContainerRequestFilter
to start transactions (in combination with the @NameBinding
annotation construction).ContainerResponseFilter
to commit transactions (if the resource method has not yet closed it).Filter
to make sure the transaction was closed, and if not, roll it back.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With