New page: I am using Jersey for a long time to implement REST services and I am relatively happy Jersey user. One thing that is problematic is the fact that I am using Jersey...
New page
I am using [[Jersey]] for a long time to implement [[REST]] services and [[I]] am relatively happy [[Jersey]] user. One thing that is problematic is the fact that [[I]] am using [[Jersey]] as a standalone application (without any J2EE container) and finding tutorials how to do it isn't always easy. For example how to use [[ComponentInjection]] with such standalone [[Jersey]] was a mystery for me for a long time...
== Injection ==
Of course, the trivial things are easy. One can use the '''javax.inject''' annotations to identify the injection slots:
<source lang="java">
@Path("/timing/") @Singleton
public final class TimingResource {
@Inject
private Storage storage;
@Inject
private ContactsResource contacts;
}
</source>
and when preparing the application register classes implementing these components into the system:
<source lang="java">
static HttpServer createServer(URI u, File dir) {
ResourceConfig rc = new ResourceConfig(
TimingResource.class, ContactsResource.class, Storage.class, Main.class
);
HttpServer server = GrizzlyHttpServerFactory.createHttpServer(u, rc);
return server;
}
</source>
that works, but it has one problem: how can I configure the instances? The system just calls their default (no argument) constructor and for example the '''Storage''' class would benefit from actually knowing the location where to store its data. So far I was solving that with a system property: Reading '''System.getProperty("storage.dir")''' inside the default constructor. That is of course quite hacky - I knew there had to be a better way, but I never invested enough time to find it out. Just today...
== Your Own Binder ==
The solution is simple. One can register own '''AbstractBinder''':
<source lang="java">
ResourceConfig rc = new ResourceConfig(
TimingResource.class, ContactsResource.class, Main.class
);
final Storage storage = dir == null ? Storage.empty() : Storage.forDirectory(dir);
rc.registerInstances(new AbstractBinder() {
@Override
protected void configure() {
bind(storage).to(Storage.class);
}
});
HttpServer server = GrizzlyHttpServerFactory.createHttpServer(u, rc);
return server;
</source>
Now it is possible to properly prepare and configure the appropriate instance of '''Storage''' and then just '''bind''' it to '''Storage.class''' when the [[Injection]] is about to happen. There is just a single downside: this is a [[Jersey]] specific solution - it uses ''org.glassfish.hk2.utilities.binding.AbstractBinder'' - but yeah, great that it works and the non ''JAX-RS'' standardized code is anyway located just in the '''main''' method initialization.
== The Real Example ==