edit

Jersey extension installer

CoreInstallersBundle / JerseyProviderInstaller

Installs various jersey extensions, usually annotated with jersey @Provider annotation and installed via environment.jersey().register():

Factory, ExceptionMapper, ValueFactoryProvider, InjectionResolver, 
ParamConverterProvider, ContextResolver, MessageBodyReader, MessageBodyWriter, 
ReaderInterceptor, WriterInterceptor, ContainerRequestFilter, 
ContainerResponseFilter, DynamicFeature, ApplicationEventListener

Recognition

Detects classes annotated with jersey @javax.ws.rs.ext.Provider annotation and register their instances in jersey.

Extensions registered as singletons, even if guice bean scope isn't set.

Due to specifics of HK integration (TODO link), you may need to use:

  • @HK2Managed to delegate bean creation to HK
  • @LazyBinding to delay bean creation to time when all dependencies will be available
  • javax.inject.Provider as universal workaround (to wrap not immediately available dependency).

Factory

Any class implementing org.glassfish.hk2.api.Factory (or extending abstract class implementing it).

@Provider
public class AuthFactory implements Factory<User>{

    @Override
    public User provide() {
        return new User();
    }

    @Override
    public void dispose(User instance) {
    }
}

Factories in essence are very like guice (or javax.inject) providers (Provider).

Example of using jersey abstract class instead of direct implementation:

@Provider
public class LocaleInjectableProvider extends AbstractContainerRequestValueFactory<Locale> {

    @Inject
    private javax.inject.Provider<HttpHeaders> request;

    @Override
    public Locale provide() {
        final List<Locale> locales = request.get().getAcceptableLanguages();
        return locales.isEmpty() ? Locale.US : locales.get(0);
    }
}

ExceptionMapper

Any class implementing javax.ws.rs.ext.ExceptionMapper (or extending abstract class implementing it). Useful for error handling customization.

@Provider
public class DummyExceptionMapper implements ExceptionMapper<RuntimeException> {

    private final Logger logger = LoggerFactory.getLogger(DummyExceptionMapper.class);

    @Override
    public Response toResponse(RuntimeException e) {
        logger.debug("Problem while executing", e);
        return Response.status(Response.Status.BAD_REQUEST)
                .type(MediaType.TEXT_PLAIN)
                .entity(e.getMessage())
                .build();
    }

}

ValueFactoryProvider

Any class implementing org.glassfish.jersey.server.spi.internal.ValueFactoryProvider (or extending abstract class implementing it).

@Provider
@LazyBinding 
public class AuthFactoryProvider extends AbstractValueFactoryProvider {

    private final Factory<User> authFactory;

    @Inject
    public AuthFactoryProvider(final MultivaluedParameterExtractorProvider extractorProvider,
                               final AuthFactory factory, 
                               final ServiceLocator injector) {
        super(extractorProvider, injector, Parameter.Source.UNKNOWN);
        this.authFactory = factory;
    }

    @Override
    protected Factory<?> createValueFactory(Parameter parameter) {
        final Auth auth = parameter.getAnnotation(Auth.class);
        return auth != null ? authFactory : null;
    }
}

Note

@LazyBinding was used to delay provider creation because required dependency MultivaluedParameterExtractorProvider (by super class) will be available only after HK context creation (which is created after guice context). Another option could be using @HK2Managed (instead of lazy) which will delegate bean creation to hk.

InjectionResolver

Any class implementing org.glassfish.hk2.api.InjectionResolver (or extending abstract class implementing it).

@Provider
@LazyBinding
public class AuthInjectionResolver extends ParamInjectionResolver<Auth> {

    public AuthInjectionResolver() {
        super(AuthFactoryProvider.class);
    }
}

Note

@LazyBinding was used to delay provider creation because super class will require hk service locator, which is not yet available. @HK2Managed could also be used instead.

ParamConverterProvider

Any class implementing javax.ws.rs.ext.ParamConverterProvider (or extending abstract class implementing it).

@Provider
public class FooParamConverter implements ParamConverterProvider {

    @Override
    public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType, Annotation[] annotations) {
        if (Foo.class.isAssignableFrom(rawType)) {
            return (ParamConverter<T>) new FooConverter();
        }
        return null;
    }

    private static class FooConverter implements ParamConverter<Foo> {
        @Override
        public Foo fromString(String value) {
            return new Foo(value);
        }

        @Override
        public String toString(Foo value) {
            return value.value;
        }
    }
}

ContextResolver

Any class implementing javax.ws.rs.ext.ContextResolver (or extending abstract class implementing it).

@Provider
public class MyContextResolver implements ContextResolver<Context> {

    @Override
    public Context getContext(Class type) {
        return new Context();
    }

    public static class Context {}
}

MessageBodyReader

Any class implementing javax.ws.rs.ext.MessageBodyReader (or extending abstract class implementing it). Useful for custom representations.

@Provider
public class TypeMessageBodyReader implements MessageBodyReader<Type> {

    @Override
    public boolean isReadable(Class<?> type, java.lang.reflect.Type genericType, Annotation[] annotations, MediaType mediaType) {
        return false;
    }

    @Override
    public Type readFrom(Class<Type> type, java.lang.reflect.Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {
        return null;
    }

    public static class Type {}
}

MessageBodyWriter

Any class implementing javax.ws.rs.ext.MessageBodyWriter (or extending abstract class implementing it). Useful for custom representations.

@Provider
public class TypeMessageBodyWriter implements MessageBodyWriter<Type> {

    @Override
    public boolean isWriteable(Class<?> type, java.lang.reflect.Type genericType, Annotation[] annotations, MediaType mediaType) {
        return false;
    }

    @Override
    public long getSize(Type type, Class<?> type2, java.lang.reflect.Type genericType, Annotation[] annotations, MediaType mediaType) {
        return 0;
    }

    @Override
    public void writeTo(Type type, Class<?> type2, java.lang.reflect.Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
    }

    public static class Type {}
}

ReaderInterceptor

Any class implementing javax.ws.rs.ext.ReaderInterceptor (or extending abstract class implementing it).

@Provider
public class MyReaderInterceptor implements ReaderInterceptor {

    @Override
    public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException {
        return null;
    }
}

WriterInterceptor

Any class implementing javax.ws.rs.ext.WriterInterceptor (or extending abstract class implementing it).

@Provider
public class MyWriterInterceptor implements WriterInterceptor {

    @Override
    void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
    }
}

ContainerRequestFilter

Any class implementing javax.ws.rs.container.ContainerRequestFilter (or extending abstract class implementing it). Useful for request modifications.

@Provider
public class MyContainerRequestFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
    }
}

ContainerResponseFilter

Any class implementing javax.ws.rs.container.ContainerResponseFilter (or extending abstract class implementing it). Useful for response modifications.

@Provider
public class MyContainerResponseFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
    }
}

DynamicFeature

Any class implementing javax.ws.rs.container.DynamicFeature (or extending abstract class implementing it). Useful for conditional activation of filters.

@Provider
public class MyDynamicFeature implements DynamicFeature {

    @Override
    public void configure(ResourceInfo resourceInfo, FeatureContext context) {
    }
}

ApplicationEventListener

Any class implementing org.glassfish.jersey.server.monitoring.ApplicationEventListener (or extending abstract class implementing it).

@Provider
public class MyApplicationEventListener implements ApplicationEventListener {

    @Override
    public void onEvent(ApplicationEvent event) {
    }

    @Override
    public RequestEventListener onRequest(RequestEvent requestEvent) {
        return null;
    }
}