Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you do traditional Servlet Filtering with JAX-RS/Jersey?

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:

  1. Using a Filter, the Jersey Servlet Container commits/flushes the response before execution returns to your filter. So, if the commit fails, you can't modify the return code to be a failure. Also, exceptions won't be caught by a JAX-RS ExceptionMapper.
  2. 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?

like image 365
Shaun Avatar asked May 13 '13 19:05

Shaun


People also ask

Is JAX-RS and Jersey same?

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.

What are valid servlet filters?

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.

What is a filter how servlet filter works give suitable example?

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.


1 Answers

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:

  1. Write an 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.
  2. Before transaction.begin(), check the current state of the transaction, and roll back there if needed.

There are problems with both options.

  1. I find an ExceptionMapper<Throwable> too broad, while the ExceptionMapper<DaoException> might miss some other exception, again leaving the transaction not cleaned up.
  2. Rolling back the transaction on the next request might take a long time, possibly causing locking issues for other transactions.

So after reading your question, I'm currently thinking:

  • Using a ContainerRequestFilter to start transactions (in combination with the @NameBinding annotation construction).
  • Using a ContainerResponseFilter to commit transactions (if the resource method has not yet closed it).
  • Using a Filter to make sure the transaction was closed, and if not, roll it back.
like image 88
drvdijk Avatar answered Sep 30 '22 04:09

drvdijk