Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jersey async request handling with programmatical resource registration

We used org.glassfish.jersey.server.model.ResourceMethod$Builder

to register the method and the handler.

ResourceMethod.Builder methodBuilder = resourceBuilder.addMethod(httpMethod);
methodBuilder.produces(restContext.getProduceContent()).handledBy(inflector);
methodBuilder.consumes(restContext.getConsumeContent()).handledBy(inflector);

The handler class implements the org.glassfish.jersey.process.Inflector<ContainerRequestContext, Response>

public class CommonMethodInflector implements Inflector<ContainerRequestContext, Response>
{
 @Override
    public Response apply(ContainerRequestContext request)
    {
      //sync bloc
      //using resqest object we do processing in different maner
        incRestFeRequestCounters(request.getMethod());
        Response response = processIncoming(request);`enter code here`
     }
}

Could you please help us in creating the async handler.

our requirement in short:

  1. At runtime only we know the http method and other resources to register. So, we can not use annotations for resource & httpMethod registration. We need only programmatic resource registration.

  2. In handler We need the request object so that we can access what method and what json body in it.

  3. we need to make the async response as we are doing huge operation in the processing request.

like image 761
Komanduri Venugopalacharyulu Avatar asked Oct 23 '25 17:10

Komanduri Venugopalacharyulu


1 Answers

The first thing you need to do is to suspend the resource method:

ResourceMethod.Builder methodBuilder = resourceBuilder.addMethod(httpMethod)
    .suspend(AsyncResponse.NO_TIMEOUT, TimeUnit.Seconds);

Then you have few choices how to process the request in async mode:

"Arbitrary" handler class

builder.addMethod("GET")
        // Suspend without time limit.
        .suspended(AsyncResponse.NO_TIMEOUT, TimeUnit.SECONDS)
        .handledBy(MyHandler.class, MyHandler.class.getMethod("handle", AsyncResponse.class));

and

public class MyHandler {

    public void handle(final @Suspended AsyncResponse response) {
        Executors.newSingleThreadExecutor().submit(new Runnable() {
            @Override
            public void run() {
                // Simulate long-running operation.
                try {
                    Thread.sleep(1000);
                } catch (final InterruptedException ie) {
                    // NOOP
                }

                response.resume("Hello World!");
            }
        });
    }
}

Inflector class

Resource.builder("helloworld")
        .addMethod("GET")
        // Suspend without time limit.
        .suspended(AsyncResponse.NO_TIMEOUT, TimeUnit.SECONDS)
        // Can be registered only as a class otherwise the
        // @Context injection would be out of request scope.
        .handledBy(MyAsyncInflector.class);

and

public class MyAsyncInflector implements Inflector<ContainerRequestContext, Response> {

    @Context
    private AsyncResponse response;

    @Override
    public Response apply(final ContainerRequestContext context) {
        Executors.newSingleThreadExecutor().submit(new Runnable() {
            @Override
            public void run() {
                // Simulate long-running operation.
                try {
                    Thread.sleep(1000);
                } catch (final InterruptedException ie) {
                    // NOOP
                }

                response.resume("Hello World!");
            }
        });

        return null;
    }
}

Annonymous Inflector

Resource.builder("helloworld")
        .addMethod("GET")
        // Suspend without time limit.
        .suspended(AsyncResponse.NO_TIMEOUT, TimeUnit.SECONDS)
        .handledBy(new Inflector<ContainerRequestContext, Response>() {

            @Inject
            private javax.inject.Provider<AsyncResponse> responseProvider;

            @Override
            public Response apply(final ContainerRequestContext context) {
                // Make sure we're in request scope.
                final AsyncResponse response = responseProvider.get();

                Executors.newSingleThreadExecutor().submit(new Runnable() {
                    @Override
                    public void run() {
                        // Simulate long-running operation.
                        try {
                            Thread.sleep(1000);
                        } catch (final InterruptedException ie) {
                            // NOOP
                        }

                        response.resume("Hello World!");
                    }
                });

                return null;
            }
        });
like image 105
Michal Gajdos Avatar answered Oct 26 '25 07:10

Michal Gajdos