Jersey 2.*. How to replace InjectableProvider and AbstractHttpContextInjectable of Jersey 1.*
Asked Answered
A

2

21

I would like to create a class whose objects can be injected using the @Context annotation (or better yet a custom annotation for cases where I need to pass an argument to the annotation) into resource methods. In Jersey 1.* I would have used InjectableProvider (in my case together with AbstractHttpContextInjectable). What I'm trying to achieve is something like @Auth [1] from dropwizard (which uses Jersey 1.7).

The injection capabilities of Jersey were replaced by HK2 as far as I know and I could not find any example of what I'm describing.

Edit: See this question for further problems I have encountered while trying to follow Michal's guide.

Acrophobia answered 27/8, 2013 at 10:47 Comment(0)
D
22

You need to implement InjectionResolver<T> interface from HK2. Take a look at existing implementations that are present in Jersey workspace:

Once you have this, you need to extend AbstractBinder from HK2 and bind your InjectionResolver via it's #configure() method:

public class MyResolverBinder extends AbstractBinder {

    @Override
    protected void configure() {
        bind(MyInjectionResolver.class)
                .to(new TypeLiteral<InjectionResolver<MyAnnotation>>() {})
                .in(Singleton.class);
    }
}

... and register an instance of this binder in your application class (or via feature):

Feature:

public class MyFeature implements Feature {

    @Override
    public boolean configure(final FeatureContext context) {
        context.register(new MyResolverBinder());
        return true;
    }
}

register MyFeature into Application:

public class JaxRsApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        final HashSet<Class<?>> classes = new HashSet<Class<?>>();
        classes.add(MyFeature.class);
        // Register other providers or resources.
        return classes;
    }
}

register MyResolverBinder or Feature in the ResourceConfig

new ResourceConfig()
        // Register either MyFeature
        .register(MyFeature.class)
        // or MyResolverBinder
        .register(new MyResolverBinder())
        // Register other providers or resources
        .packages("my.package");
Dowlen answered 27/8, 2013 at 12:5 Comment(5)
Thanks! That seems to be exactly what I need.Acrophobia
Michal, I tried to follow your guide, but I have encountered a weird warning "... A HTTP GET method ... should not consume any entity.". I'm not sure what to make of that (see edit of my question for more details). Do you have any ideas as to what might be causing it? Thanks.Acrophobia
Thanks for the answer. However, it's unclear to me how to create an object given, say, the ContainerRequestContext and how to correctly dispose of the injected object, e.g., by calling close(). I can't find any example online, do you have suggestions?Pimple
ContainerRequestContext is created for you by Jersey (you can access it in the provider). If you need to dispose the object try implementing a @PreDestroy method.Dowlen
Am I the only one that has a feeling this has gone from very simple and concise in Jersey 1.x to extremely overly engineer and cumbersome in 2.x?Folkway
M
4

Providing an implementation of InjectionResolver only helps with injection, not when resolving values for the parameters of a resource method.

At least with Jersey 2.11, you need to define a ValueFactoryProvider annotated with @Provider.

@Provider
public class MyValueFactoryProvider implements ValueFactoryProvider {

    @Inject
    private MyFactory factory;

    @Override
    public Factory<?> getValueFactory(Parameter parameter) {
        if (parameter.getAnnotation(MyAnnotationParam.class) != null) {
            return factory;
        }

        return null;
    }

    @Override
    public PriorityType getPriority() {
        return Priority.NORMAL;
    }

}

If you also want to get the value injected in, e.g., members and constructor parameters, then InjectionResolver works well.

Maquette answered 20/9, 2014 at 10:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.