Search code examples
javajerseyjettydropwizard

jersey requestdispatcher execution order


I am trying to implement a RequestDispatcher using dropwizard that is supposed to look at Entity in body on posts and calculate certain stats.

so, i implemented a ResourceMethodDispatchAdapter and ResourceMethodDispatchProvider and I am able to successfully inject and invoke my RequestDispatcher,

 private static class InspectRequestDispatcher implements RequestDispatcher {

    private final RequestDispatcher dispatcher;

    private InspectRequestDispatcher(RequestDispatcher dispatcher) {
        this.dispatcher = dispatcher;
    }

    @Override
    public void dispatch(final Object resource, final HttpContext context) {
        final Saying day = context.getRequest().getEntity(Saying.class);
        dispatcher.dispatch(resource, context); // this throws ConstraintViolationException
    }
}

The above code throws exception, since i have already read the body ( which is understandable ), I could reset the stream, but then i will pay the penalty for reading the body twice.

Is it possible to intercept method invocation AFTER parameters have been injected ? somehow schedule this interceptor to be the last one ?

using dropwizard 7 version


Solution

  • If you were to use a ContainerRequestFilter instead of a RequestDispatcher, you could make use of the CachedEntityContainerRequest that's meant for exactly this.

    A cached entity in-bound HTTP request that caches the entity instance obtained from the adapted container request.

    A filter may utilize this class if it requires an entity of a specific type and that same type will also be utilized by a resource method.

    You'd basically use it like so:

    @Provider
    public class StatsFilter implements ContainerRequestFilter {
        @Override
        public ContainerRequest filter(ContainerRequest request) {
            final CachedEntityContainerRequest cachedRequest
                    = new CachedEntityContainerRequest(request);
    
            final Saying saying = cachedRequest.getEntity(Saying.class);
    
            return cachedRequest;
        }
    }
    

    Then just register the filter.