Search code examples
jerseyhk2

Registering a custom ResourceMethodInvocationHandler in Jersey


I am attempting to intercept a resource call after it's JSON has been unmarshalled. Reading through some forums and posts I discovered that I may be able to do so by implementing org.glassfish.jersey.server.spi.internal.ResourceMethodInvocationHandlerProvider. Having done so I am now stuck trying to get my CustomResourceMethodInvocationHandler provider registered so that the jersey/hk2 internals call my overridden public InvocationHandler create(Invocable invocable) method. Any help would be much appreciated!


Solution

  • Let's have a look at this approach:

    (Tested with Jersey 2.10 and JSON serialization)

    ==============

    1) Implement a custom ResourceMethodInvocationHandlerProvider

    package com.example.handler;
    
    import java.lang.reflect.InvocationHandler;
    
    import org.glassfish.jersey.server.model.Invocable;
    import org.glassfish.jersey.server.spi.internal.ResourceMethodInvocationHandlerProvider;
    
    public class CustomResourceInvocationHandlerProvider implements
            ResourceMethodInvocationHandlerProvider {
    
        @Override
        public InvocationHandler create(Invocable resourceMethod) {
                return new MyIncovationHandler();
        }
    
    }
    

    2) Implement a custom InvocationHandler

    package com.example.handler;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class MyIncovationHandler implements InvocationHandler {
    
        @Override
        public Object invoke(Object obj, Method method, Object[] args)
                throws Throwable {
            // optionally add some logic here
            Object result = method.invoke(obj, args);
            return result;
        }
    }
    

    3) Create a custom Binder class and register your CustomResourceInvocationHandlerProvider

    package com.example.handler;
    
    import org.glassfish.hk2.utilities.binding.AbstractBinder;
    import org.glassfish.jersey.server.spi.internal.ResourceMethodInvocationHandlerProvider;
    
    public class CustomBinder extends AbstractBinder {
    
        @Override
        protected void configure() {
            // this is where the magic happens!
            bind(CustomResourceInvocationHandlerProvider.class).to(
                    ResourceMethodInvocationHandlerProvider.class);
        }
    }
    

    4) Optionally: Set breakpoint in ResourceMethodInvocationHandlerFactory

    Just to understand how the selection of ResourceMethodInvocationHandlerProvider in org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory works.

    ==============

    As you can see, the most important thing is to bind your CustomResourceInvocationHandlerProvider.class to the ResourceMethodInvocationHandlerProvider.class. After doing this, HK2 knows about your Provider and also about your Handler!

    Hope, I could help.