@Override protected void configure() { jerseyToGuice(MultivaluedParameterExtractorProvider.class); jerseyToGuice(Application.class); jerseyToGuice(Providers.class); // request scoped objects, but hk will control their scope // must be used in guice only with Provider jerseyToGuice(UriInfo.class); jerseyToGuice(ResourceInfo.class); jerseyToGuice(HttpHeaders.class); jerseyToGuice(SecurityContext.class); jerseyToGuice(Request.class); jerseyToGuice(ContainerRequest.class); jerseyToGuice(AsyncContext.class); if (!guiceServletSupport) { // bind request and response objects when guice servlet module not registered // but this will work only for resources jerseyToGuice(HttpServletRequest.class); jerseyToGuice(HttpServletResponse.class); } }
/** * Uses {@link AsyncContext} to suspend current request * * @return obtained {@link AsyncContext} or throws error */ private AsyncContext suspend() { final AsyncContext context = asyncContext.get(); if (!context.suspend()) { throw new ProcessingException(LocalizationMessages.ERROR_SUSPENDING_ASYNC_REQUEST()); } return context; }
@Override public Response dispatch(Object resource, ContainerRequest request) throws ProcessingException { final AsyncContext context = this.asyncContext.get(); if(!context.suspend()) throw new ProcessingException(LocalizationMessages.ERROR_SUSPENDING_ASYNC_REQUEST()); final ContainerRequestContext requestContext = containerRequestContext.get(); Publisher pub = (Publisher)originalDispatcher.dispatch(resource, request) .getEntity(); Spouts.from(pub).onEmptySwitch(()->Spouts.of(Response.noContent().build())) .forEach(1,context::resume, context::resume); return null; }
@Override void setContext(RequestScope requestScope, Instance requestScopeInstance, ContainerRequest requestContext, ContainerResponse responseContext, ConnectionCallback connectionCallbackRunner, Value<AsyncContext> asyncContext) throws IOException { super.setContext(requestScope, requestScopeInstance, requestContext, responseContext, connectionCallbackRunner, asyncContext); latch.countDown(); }
@Override public Response dispatch(Object resource, ContainerRequest request) throws ProcessingException { final AsyncContext asyncContext = suspend(); dispatch(asyncContext, originalDispatcher, resource, request); return null; //should return null for dispatch requests }
/** * Should execute interceptors, dispatch and resume with {@link AsyncContext} * * @param asyncContext Async Context * @param dispatcher original {@link ResourceMethodDispatcher} * @param resource the resource class instance. * @param request request to be dispatched. * @throws ProcessingException same as {@link ResourceMethodDispatcher#dispatch(Object, ContainerRequest)} */ public abstract void dispatch(AsyncContext asyncContext, ResourceMethodDispatcher dispatcher, Object resource, ContainerRequest request) throws ProcessingException;