Jersey extension installer¶
CoreInstallersBundle / JerseyProviderInstaller
Installs various jersey extensions, usually annotated with jersey @Provider
annotation and installed via environment.jersey().register()
:
Supplier, ExceptionMapper, ValueParamProvider, InjectionResolver,
ParamConverterProvider, ContextResolver, MessageBodyReader, MessageBodyWriter,
ReaderInterceptor, WriterInterceptor, ContainerRequestFilter,
ContainerResponseFilter, DynamicFeature, ApplicationEventListener, ModelProcessor
Recognition¶
Detects known jersey extension classes and classes annotated with jersey @jakarta.ws.rs.ext.Provider
annotation and register their instances in jersey.
Extensions registered as singletons, when no explicit scope annotation is used. Behaviour could be disabled with option:
.option(InstallerOptions.ForceSingletonForJerseyExtensions, false)
Before guicey 5.7.0 it was required to annotate all extensions with @Provide
, but now
it is not required - extension would be recognized by implemented interface.
But, if you prefer legacy behaviour then it could be reverted with:
.option(InstallersOptions.JerseyExtensionsRecognizedByType, false)
Special @Prototype
scope annotation may be used to mark resources in prototype scope.
It is useful when guice servlet support is disabled (and so @RequestScoped
could not be used).
Due to specifics of HK2 integration, you may need to use:
@JerseyManaged
to delegate bean creation to HK2@LazyBinding
to delay bean creation to time when all dependencies will be availablejakarta.inject.Provider
as universal workaround (to wrap not immediately available dependency).
Or you can enable HK2 management for jersey extensions by default. Note that this will affect resources too and guice aop will not work on jersey extensions.
Priority¶
By default, all registered providers are qualified with @org.glassfish.jersey.internal.inject.Custom
to
prioritize them (be able to override dropwizard defaults). This mimics the default behaviour
of manual registration with environment.jersey().register(...)
.
For example, when you register your own ExceptionMapper<Throwable>
it would be used instead
of default dropwizard one (due to prioritized qualification).
For more details see org.glassfish.jersey.internal.inject.Providers#getAllServiceHolders(
org.glassfish.jersey.internal.inject.InjectionManager, java.lang.Class)
which is used by jersey for providers loading.
Tip
Previously (<= 5.2.0) guicey were not qualifying providers and qualification may (unlikely, but can!) introduce behaviour changes on guicey upgrade (due to prioritized custom providers). In this case, auto qualification may be disabled with
.option(InstallerOptions.PrioritizeJerseyExtensions, false)
@Custom
may be used directly in this case on some providers for prioritization.
@Priority
annotation may be used for ordering providers. Value should be > 0 (but may be negative, just a convention).
For example, 1000 is prioritized before 2000. See jakarta.ws.rs.Priorities
for default priority constants.
Note
@Priority
may work differently on @Custom
qualified providers (all user providers by default)
and unqualified (e.g. registered through hk module, like dropwizard defaults). Right now, qualified
providers sorted ascending while unqualified sorted descending (due to different selection implementations,
see getAllServiceHolders
reference above). Probably a jersey bug.
Supplier¶
Warning
Supplier
is used now by hk2 as a replacement to its own Factory
interface.
If you were using AbstractContainerRequestValueFactory
then use just Supplier<T>
instead.
Any class implementing java.util.function.Supplier
(or extending abstract class implementing it).
public class MySupplier implements Supplier<MyModel> {
@Override
public MyModel get() {
...
}
}
Suppliers in essence are very like guice (or jakarta.inject
) providers (Provider
).
Warning
Previously, factories were used as auth objects providers. Now Function<ContainerRequest, ?>
must be used instead:
@Provider
class AuthFactory implements Function<ContainerRequest, User> {
@Override
public User apply(ContainerRequest containerRequest) {
return new User();
}
}
ExceptionMapper¶
Any class implementing jakarta.ws.rs.ext.ExceptionMapper
(or extending abstract class implementing it).
Useful for error handling customization.
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();
}
}
Tip
You can also use ExtendedExceptionMapper
as more flexible alternative. See example usage in
dropwizard-views.
Tip
Default exception dropwizard mappers (registered in io.dropwizard.setup.ExceptionMapperBinder
) could be
overridden
(see priority section)
or completely disabled with server.registerDefaultExceptionMappers
option.
ValueParamProvider¶
Any class implementing org.glassfish.jersey.server.spi.internal.ValueParamProvider
(or extending abstract class implementing it).
public class AuthFactoryProvider extends AbstractValueParamProvider {
private final AuthFactory authFactory;
@Inject
public AuthFactoryProvider(final jakarta.inject.Provider<MultivaluedParameterExtractorProvider> extractorProvider,
final AuthFactory factory) {
super(extractorProvider, Parameter.Source.UNKNOWN);
this.authFactory = factory;
}
@Override
protected Function<ContainerRequest, User> createValueProvider(Parameter parameter) {
final Auth auth = parameter.getAnnotation(Auth.class);
return auth != null ? authFactory : null;
}
}
InjectionResolver¶
Any class implementing org.glassfish.hk2.api.InjectionResolver
(or extending abstract class implementing it).
class MyObjInjectionResolver implements InjectionResolver<MyObjAnn> {
@Override
public Object resolve(Injectee injectee) {
return new MyObj();
}
@Override
public Class<MyObjAnn> getAnnotation() {
return MyObjAnn.class;
}
@Override
public boolean isConstructorParameterIndicator() {
return false;
}
@Override
public boolean isMethodParameterIndicator() {
return true;
}
}
ParamConverterProvider¶
Any class implementing jakarta.ws.rs.ext.ParamConverterProvider
(or extending abstract class implementing it).
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 jakarta.ws.rs.ext.ContextResolver
(or extending abstract class implementing it).
public class MyContextResolver implements ContextResolver<Context> {
@Override
public Context getContext(Class type) {
return new Context();
}
public static class Context {}
}
MessageBodyReader¶
Any class implementing jakarta.ws.rs.ext.MessageBodyReader
(or extending abstract class implementing it).
Useful for custom representations.
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 jakarta.ws.rs.ext.MessageBodyWriter
(or extending abstract class implementing it).
Useful for custom representations.
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 jakarta.ws.rs.ext.ReaderInterceptor
(or extending abstract class implementing it).
public class MyReaderInterceptor implements ReaderInterceptor {
@Override
public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException {
return null;
}
}
WriterInterceptor¶
Any class implementing jakarta.ws.rs.ext.WriterInterceptor
(or extending abstract class implementing it).
public class MyWriterInterceptor implements WriterInterceptor {
@Override
void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
}
}
ContainerRequestFilter¶
Any class implementing jakarta.ws.rs.container.ContainerRequestFilter
(or extending abstract class implementing it).
Useful for request modifications.
public class MyContainerRequestFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
}
}
ContainerResponseFilter¶
Any class implementing jakarta.ws.rs.container.ContainerResponseFilter
(or extending abstract class implementing it).
Useful for response modifications.
public class MyContainerResponseFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
}
}
DynamicFeature¶
Any class implementing jakarta.ws.rs.container.DynamicFeature
(or extending abstract class implementing it).
Useful for conditional activation of filters.
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).
public class MyApplicationEventListener implements ApplicationEventListener {
@Override
public void onEvent(ApplicationEvent event) {
}
@Override
public RequestEventListener onRequest(RequestEvent requestEvent) {
return null;
}
}
ModelProcessor¶
Any class implementing org.glassfish.jersey.server.model.ModelProcessor
(or extending abstract class implementing it).
public class MyModelProcessor implements ModelProcessor {
@Override
public ResourceModel processResourceModel(ResourceModel resourceModel,
Configuration configuration) {
return resourceModel;
}
@Override
public ResourceModel processSubResource(ResourceModel subResourceModel,
Configuration configuration) {
return subResourceModel;
}
}