-
-
Save mdonkers/a48bfeef62d979412861 to your computer and use it in GitHub Desktop.
Jersey 2 custom injection of method parameters (incl Spring integration)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Annotation for injecting {@link Identity} objects into Jersey Resource implementations Use annotation | |
* for fields, method parameter or method based injection. | |
*/ | |
@Retention(RetentionPolicy.RUNTIME) | |
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD }) | |
public @interface IdentityParam { | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Class to take {@link Identity} object from the Http Request attributes and make sure it can be | |
* automatically injected in resources. | |
*/ | |
@Singleton | |
final class IdentityParamValueFactoryProvider extends AbstractValueFactoryProvider { | |
/** | |
* Injection resolver for {@link IdentityParam} annotation. Will create a Factory Provider for | |
* the actual resolving of the {@link Identity} object. | |
*/ | |
@Singleton | |
static final class InjectionResolver extends ParamInjectionResolver<IdentityParam> { | |
/** | |
* Create new {@link IdentityParam} annotation injection resolver. | |
*/ | |
public InjectionResolver() { | |
super(IdentityParamValueFactoryProvider.class); | |
} | |
} | |
/** | |
* Factory implementation for resolving request-based attributes and other information. | |
*/ | |
private static final class IdentityParamValueFactory extends AbstractContainerRequestValueFactory<Identity> { | |
@Context | |
private ResourceContext context; | |
/** | |
* Fetch the Identity object from the request. Since HttpServletRequest is not directly available, we need to get it via | |
* the injected {@link ResourceContext}. | |
* | |
* @return {@link Identity} stored on the request, or NULL if no object was found. | |
*/ | |
public Identity provide() { | |
final HttpServletRequest request = context.getResource(HttpServletRequest.class); | |
final Identity identity = (Identity) request.getAttribute(IDENTITY_ATTRIBUTE); | |
return identity; | |
} | |
} | |
/** | |
* {@link IdentityParam} annotation value factory provider injection constructor. | |
* | |
* @param mpep | |
* multivalued parameter extractor provider. | |
* @param injector | |
* injector instance. | |
*/ | |
@Inject | |
public IdentityParamValueFactoryProvider(MultivaluedParameterExtractorProvider mpep, ServiceLocator injector) { | |
super(mpep, injector, Parameter.Source.UNKNOWN); | |
} | |
/** | |
* Return a factory for the provided parameter. We only expect {@link Identity} objects being annotated with | |
* {@link IdentityParam} annotation | |
* | |
* @param parameter | |
* Parameter that was annotated for being injected | |
* @return {@link IdentityParamValueFactory} if parameter matched {@link Identity} type | |
*/ | |
@Override | |
public AbstractContainerRequestValueFactory<?> createValueFactory(Parameter parameter) { | |
Class<?> classType = parameter.getRawType(); | |
if (classType == null || (!classType.equals(Identity.class))) { | |
LOG.warn("IdentityParam annotation was not placed on correct object type; Injection might not work correctly!"); | |
return null; | |
} | |
return new IdentityParamValueFactory(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Jersey Controller for handling REST calls. | |
*/ | |
@Produces({ MediaType.APPLICATION_JSON }) | |
@Consumes({ MediaType.APPLICATION_JSON }) | |
@Path("/") | |
public class MyResource { | |
@GET | |
public Response getSomeValue(@IdentityParam final Identity identity) { | |
// Do work and return something | |
return Response.status(OK).entity(myValue).build(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* {@link ResourceConfig} instance class for configuration of Jersey 2.x specific settings. Class should be loaded by | |
* applications (next to Spring configuration) from the web.xml. | |
*/ | |
public class RestResourceConfig extends ResourceConfig { | |
/** | |
* Internal {@link AbstractBinder} implementation to register our needed bindings for injecting parameters. | |
*/ | |
private static final class InjectionBinder extends AbstractBinder { | |
/** | |
* Implement to provide binding definitions using the exposed binding methods. | |
*/ | |
@Override | |
protected void configure() { | |
bind(IdentityParamValueFactoryProvider.class).to(ValueFactoryProvider.class).in(Singleton.class); | |
bind(IdentityParamValueFactoryProvider.InjectionResolver.class).to( | |
new TypeLiteral<InjectionResolver<IdentityParam>>() { | |
}).in(Singleton.class); | |
} | |
} | |
/** | |
* Constructor, used to setup all bindings for the HK2 DI service, so that we can inject our own objects. Register all classes | |
* that provide certain Jersey features. E.g. the {@link JacksonFeature} must be loaded to enable Jackson object mapping to | |
* JSON | |
*/ | |
public RestResourceConfig() { | |
LOG.debug("====> Registering features and injection providers ===="); | |
// Register all general provider classes (annotated with @provider) | |
packages("nl.codecentric.rest.providers"); | |
// Register the Jackson object mapper | |
register(JacksonFeature.class); | |
// Register injection bindings, InjectionBinder needs to be instantiated for some reason | |
register(new InjectionBinder()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<servlet> | |
<servlet-name>jersey-servlet</servlet-name> | |
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> | |
<init-param> | |
<param-name>javax.ws.rs.Application</param-name> | |
<param-value>nl.codecentric.rest.providers.RestResourceConfig</param-value> | |
</init-param> | |
<init-param> | |
<!-- Package that is being scanned for resources (interface) --> | |
<param-name>jersey.config.server.provider.packages</param-name> | |
<param-value> | |
nl.codecentric.app.resources | |
</param-value> | |
</init-param> | |
<load-on-startup>2</load-on-startup> | |
</servlet> | |
<servlet-mapping> | |
<servlet-name>jersey-servlet</servlet-name> | |
<url-pattern>/rest/*</url-pattern> | |
</servlet-mapping> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment